Передача массивных аргументов в функции Python

Вопросы и ответы

Я пишу код, который выполняет матричные операции в функциях, и я использую массивы numpy для хранения моих матриц. Из книг и обсуждений здесь я понял, что скалярные аргументы функций передаются по значению, а массивы передаются способом, похожим на C (в C мы бы сказали, что передается указатель на массив, и эквивалентное действие происходит в Python).

Вот два простых кода на Python, первый из которых успешно умножает 2 матрицы и передает результат обратно в вызываемый код. Я достиг этого, вручную реализовав умножение матриц, следуя подсказке, которую я видел здесь (или на аналогичном форуме). Во втором я заменяю ручное умножение матриц на c=np.dot(a,b), и произведение матриц не передается обратно.

Как заставить работать второй подход?

Пример 1:

import numpy as np
def my_func(a,b,c):
    for i in range (0,2):
        for j in range (0,2):
            c[i,j]=0.
            for k in range(0,2):
                c[i,j]=c[i,j]+a[i,k]*b[k,j]
    print("c")
    print(c)
d = np.array([[1,2],[3,4]])
e = np.array([[-1,3],[2,-1]])
f = np.zeros((2,2))
my_func(d,e,f)
print("f")
print(f)

и вот вывод:

c
[[3. 1.]
 [5. 5.]]
f
[[3. 1.]
 [5. 5.]]

Пример 2:

import numpy as np
def my_func(a,b,c):
    c=np.dot(a,b)
    print("c")
    print(c)
d = np.array([[1,2],[3,4]])
e = np.array([[-1,3],[2,-1]])
f = np.zeros((2,2))
my_func(d,e,f)
print("f")
print(f)

и вот вывод:

c
[[3 1]
 [5 5]]
f
[[0. 0.]
 [0. 0.]]

Ответ

Для решения вашей проблемы с возвратом результирующей матрицы при использовании функции np.dot в Python вы должны учитывать, что при присваивании в функции, как в вашем втором примере, переменной c внутри функции вы фактически создаете новую локальную переменную, а не изменяете элемент f, который был передан в функцию. Чтобы передать результирующую матрицу обратно, необходимо вернуть значение из функции.

Вот как можно модифицировать ваш второй пример, чтобы он работал так, как задумано:

import numpy as np

def my_func(a, b):
    c = np.dot(a, b)  # здесь мы создаем новую матрицу c
    print("c")
    print(c)
    return c  # возвращаем значение c

d = np.array([[1, 2], [3, 4]])
e = np.array([[-1, 3], [2, -1]])
f = my_func(d, e)  # теперь мы вызываем функцию и присваиваем результат переменной f
print("f")
print(f)

Вывод будет следующим:

c
[[3 1]
 [5 5]]
f
[[3 1]
 [5 5]]

Таким образом, с точки зрения передачи массивов (numpy массивов в вашем случае), когда вы хотите, чтобы изменения, сделанные в функции, были видны вне ее, вы можете либо изменять сам массив, как в вашем первом примере, либо возвращать новый массив, как в исправленном примере второго.

Использование второго подхода (возврат значения) часто более предпочтительно, поскольку это делает функции более чистыми и предсказуемыми.

Оцените материал
Добавить комментарий

Капча загружается...