python中函数参数的引用与传值

最近自己写了个函数,实现numpy数组180度旋转的功能:

import numpy as np
def rotate(matrix):

    if matrix.ndim == 2:
        matrix = list(matrix)
        for i in range(2):
            #一次顺时针旋转90度
            matrix[:] = map(list,zip(*matrix[::-1]))
        return np.array(matrix)
    elif matrix.ndim == 3:
        for j in range(matrix.shape[0]):
            matrix[j] = rotate(matrix[j])
        return np.array(matrix)

待旋转矩阵weights2

weights2 = np.array(
[[[2,2,1],
[1,2,1],
[1,2,0]],

[[1,0,1],
[1,1,1],
[1,2,0]],

[[0,0,2],
[1,2,1],
[0,1,1]]])

函数输出
观察一下,发现输出正确,但再次输出weights2时,发现也跟着旋转了
这里写图片描述
很好奇为啥只是作为函数输入的weights2在函数内部会被修改,后来了解到python中可变参数一般是参数引用而不是参数传值,对于一般的赋值也是如此。
比如:

matrix = weights2
print(weights2)
print(id(weights2),'\n',id(matrix))
matrix[0][0][0] = 10
print(weights2)

这里写图片描述
发现直接赋值时,两个变量的ID竟然是相同的,也就是两个变量完全等价,任意一个变量修改都会影响到另一个。试试下一种赋值方法

matrix = weights2[:]
print(weights2)
print(id(weights2),'\n',id(matrix))
matrix[0][0][0] = 10
print(weights2)

这里写图片描述
两个变量不相同,但是变量指向的元素地址却相同,所以二者还是相关联的。
再来看一种情况如下:

matrix = weights2[0]
print(weights2)
print(id(weights2),'\n',id(matrix))
matrix[0][0] = 10
print(weights2)

这里写图片描述
即使只取weights2[0]赋给matrix,但二者还是共享变量地址,因此二者还是相关联的。
如何避免两个变量相关联的情况呢,可以对原来的变量进行一些运算,因为有运算,所以会另外开辟地址保存运算结果,并将运算结果赋值给左端变量matrix,使得matrix与weights2两个变量指向的地址不再相同。

matrix = weights2 + 0
print(weights2)
print(id(weights2),'\n',id(matrix))
matrix[0][0][0] = 10
print(weights2)

这里写图片描述
这次总算实现了对matrix修改,而weights2保持不变了。

最后贴上我对rotate函数的两种修改:

def rotate(matrix):
    if matrix.ndim == 2:
        matrix = list(matrix)
        for i in range(2):
            #一次顺时针旋转90matrix[:] = map(list,zip(*matrix[::-1]))
        return np.array(matrix)
    elif matrix.ndim == 3:
        matrix = matrix + 0.0
        for j in range(matrix.shape[0]):
            matrix[j] = rotate(matrix[j])
        return np.array(matrix)
def rotate(matrix):
    matrix1 = list(matrix)
    if matrix.ndim == 2:
        for i in range(2):
            #一次顺时针旋转90度
            matrix1[:] = map(list,zip(*matrix1[::-1]))
        return np.array(matrix1)
    elif matrix.ndim == 3:
        for j in range(matrix.shape[0]):
            matrix1[j] = rotate(matrix1[j])
        return np.array(matrix1)

后面一种在开始就对matrix取list,因此也会另外开辟地址保存数据。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值