【编程语言】python的赋值

赋值是语言里最基本的语句,我到现在才发现我之前对python里的赋值的理解一直都是错的。 

python里的赋值使用的是原对像的引用,而不是拷贝。因此,在进行b=a这样的赋值之后,对b进行操作,是有可能会影响a的值的。例如: 
>>> a = [1,2,3] 
>>> b = a 
>>> b.append(4) 
>>> print(a,b) 
[1, 2, 3, 4] [1, 2, 3, 4] 

使用 += 也有一样的效果: 
>>> a = [1,2,3] 
>>> b = a 
>>> b += [4] 
>>> print(a,b) 
[1, 2, 3, 4] [1, 2, 3, 4] 

但是,对b进行重新赋值,则不影响a 
>>> a = [1,2,3] 
>>> b = a 
>>> b = a + [4] 
>>> print (a,b) 
[1, 2, 3] [1, 2, 3, 4] 
因为a+[4]是通过拷贝生成了新的对像,然后把b重新绑定到新的对像上,此后b和a就没有关系了。 
由这个例子可以看出:b += a 并不总是等价于 b = b + a 的 

函数的参数传递跟赋值的道理相同。在C语言书上讲函数的参数传递时有个的例子,是在函数体中交换两个变量的值,并不影响函数体外的变量。这很容易让人觉得函数体内是与世隔绝的,形参随便改用都不会对外面有影响。但这套用到python上就不对了,虽然python跟C语言中传值的写法相同,没有使用明显的指针或取地址运行符,但确实是使用了引用的方式进行传递。因此,python函数体内对形参进行的操作也有可能对外面有副作用,需要留意。 
>>> def fun(a): 
    a += a 
    print(a) 

>>> x = [1,2,3] 
>>> fun(x) 
[1, 2, 3, 1, 2, 3] 
>>> print(x) 
[1, 2, 3, 1, 2, 3] 

不过,当使用数字、元组、字符串等不可变的对像时,情况又不一样了。同样是上面那个fun函数,以字符串为参数时: 
>>> s = 'abc' 
>>> fun(s) 
abcabc 
>>> print(s) 
abc 
字符串s在fun运行完后并没有被改变,因为字符串是不可变的对像,字符串的+=操作与数组的+=操作不一样,前者进行了拷贝,后者没有。 

python中数组的构建同样涉及到引用的问题。我们构建一维数组可以简单的使用乘号*来完成 
>>> A = [0]*5 
>>> print(A) 
[0, 0, 0, 0, 0] 
>>> A[1] = 1 
>>> print(A) 
[0, 1, 0, 0, 0] 

但是,在第二维就不可以这么做了 
>>> A = [0]*5 
>>> B = [A]*3 
>>> print(B) 
[[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]] 
>>> B[1][1]=1 
>>> print(B) 
[[0, 1, 0, 0, 0], [0, 1, 0, 0, 0], [0, 1, 0, 0, 0]] 
>>> print(A) 
[0, 1, 0, 0, 0] 

因为B=[A]*3就是B=[A,A,A],B里的三个元素是指向同一个对像的,B[1][1]=1就会同时修改三行中的值,这样构建出来的数组一般是不适用的。此时构建多维数组就必需要使用拷贝的方法进行。 
对数组进行拷贝有多种方法, 
>>> A = [1,2,3,4,5] 
>>> B = A[:] 
>>> C = [x for x in A] 
>>> D = list(A) 
B、C、D都是A的拷贝,对其进行修改不会对A有影响。 
数组的第二维要用for进行,如: 
>>> E = [A[:] for i in range(3)] 
>>> F = [[x for x in A] for i in range(3)] 
>>> G = [list(A) for i in range(3)] 

对于一般对像的拷贝,可以用copy模块。 
>>> import copy 
>>> A = [1,2,3] 
>>> B = copy.copy(A) 
copy.copy()可以生成对像的浅拷贝,前面使用的数据拷贝方法都是浅拷贝。如果要对对像的内容和属性进行分别的和递归的拷贝,可以使用copy.deepcopy() 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值