В чем разница? numpy.array проходит по ссылке

Почему у нас два разных поведения на этих np.array?

    def pass_by_ref(A: np.array):
        A = np.ones((2,2))
        return A

    def pass_by_ref_sideEffect(A: np.array):
        A[0][0] = 2
        return A


    A = np.zeros((2,2))

    B = pass_by_ref(A)
    print("A =\n", A)
    print("B =\n", B)

    C = pass_by_ref_sideEffect(A)
    print("A =\n", A)
    print("C =\n", C)

выход:

    A =
     [[0. 0.]
     [0. 0.]]
    B =
     [[1. 1.]
     [1. 1.]]
    A =
     [[2. 0.]
     [0. 0.]]
    C =
     [[2. 0.]
     [0. 0.]]

Почему у нас есть побочный эффект на A после pass_by_ref_sideEffect, а не с pass_by_ref?

Объекты передаются по ссылке, переменные — нет.

Barmar 22.04.2022 19:47

так что мы не передаем A по ссылке? все же у нас есть два поведения

FioreTom 22.04.2022 19:49
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
2
39
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Это не имеет ничего общего с тем, как вы передаете переменную, и все, что связано с тем, как работает присваивание. В pass_by_ref() эта строка A = np.ones((2,2)) создает новый массив и присваивает ему локальное имя A. Исходный объект массива все еще существует, но A больше не ссылается на него. В другом случае вы манипулируете исходным массивом, присваивая его элементу с помощью A[0][0] = 2.

Если вы хотите иметь побочный эффект в первом случае, то назначьте срезу А вот так:

def pass_by_ref(A: np.array):
    A[:,:] = np.ones((2,2))
    return A

A = np.zeros((2,2))
B = pass_by_ref(A)

print(A)
[[1., 1.],
 [1., 1.]]

print(B)
[[1., 1.],
 [1., 1.]]

Вот пример, демонстрирующий это без передачи переменных в функции:

In [1]: import numpy as np

In [2]: A = np.zeros((2,2))

In [3]: B = A

In [4]: B
Out[4]:
array([[0., 0.],
       [0., 0.]])

In [5]: A[:,:] = np.ones((2,2))

In [6]: B
Out[6]:
array([[1., 1.],
       [1., 1.]])

Когда Python вызывает функцию, он передает ссылку на объект. Когда вы используете A[0][0] = 2 для назначения, оно будет смещено в соответствии с адресом объекта, на который указывает переменная A, найдите адрес для записи. Но если вы используете A = np.ones((2, 2)), будет создан новый массив, и переменная make A будет указывать на него.

Другие вопросы по теме