Chinaunix
标题:
Python中的增强赋值
[打印本页]
作者:
中关村村草
时间:
2011-03-04 10:36
标题:
Python中的增强赋值
转:
Yao
Python中的增强赋值
从2.0开始,Python支持一组额外的赋值语句,称为增强赋值语句(Augmented assignment statements),比如“-=”,“+=”,“/=”等等。所谓“增强”是与通常写法比较而言,学过其它类似C,Java,C#等语言的同学都知道,“a += b”其实就等于"a = a + b",只是写法上有所简化。但在Python里,事情却没那么简单,里面猫腻还真不少……
为了方便查看内存的变化,需要用到“id”这个方法,它会返回python对象的整型标识符,其实在多数情况下这个“标识符”就是对象的内存地址,使用help(id),可以看到说明如下:
1 id(...)
2 id(object) -> integer
3
4 Return the identity of an object. This is guaranteed to be unique among
5 simultaneously existing objects. (Hint: it's the object's memory address.)
复制代码
后面的代码使用str(hex(id(...)))来打印出变量的地址。
先来看demo:
01 # -*- coding: utf-8 -*-
02
03 lst = [1,2,3,4]
04
05 print("Before: ", str(hex(id(lst))))
06
07 lst2 = lst
08 print("List2 : ",str(hex(id(lst2))))
09
10 lst = lst + [5,6] #普通赋值语句
11 #lst += [5,6] #增强赋值语句
12
13 print("After : ", str(hex(id(lst))))
14
15 print( lst is lst2 )
复制代码
在我机子上,输出为(注意:运行时具体数值可能会不同):
1 ('Before: ', '0xb786c5acL')
2 ('List2 : ', '0xb786c5acL')
3 ('After : ', '0xb788174cL')
4 False
复制代码
可以看到,lst2 与lst地址相同,也就是说他们指向了同一个对象,就是所谓的"共享引用",这与预期相同。
第10行代码,lst与另外一个列表([5,6])做"+“运算时,首先会生成一个新的列表对象,然后lst指向这个新对象,这个过程中lst参与了两次运算(一次是参与新对象生成,第二次是指向新对象),这也在我们期望之中。
接下来,注释掉第10行代码,并取消第11行的注释,再次运行程序,结果如下:
1 ('Before: ', '0xb77355acL')
2 ('List2 : ', '0xb77355acL')
3 ('After : ', '0xb77355acL')
4 True
复制代码
地址没变?!什么情况?原来在使用增强赋值语句时,Python会在可能的情况下执行原地(in-place)修改,比如,上面的代码,python会在lst原来的内存空间的后面“扩展”一些内存,用来存放[5,6],这样,lst其实只参与了一次运算,而且没有发生额外的内存复制,所以要比普通赋值语句执行更快!
在demo的第9行和第16行添加下面的代码,可以查看列表内每个元素的地址,来验证前面的结论。
1 for item in lst:
2 print("Item%d: %x"%(item,id(item)))
复制代码
可以看到地址是连续的:
01 ('Before: ', '0xb77585acL')
02 ('List2 : ', '0xb77585acL')
03 Item1: 9d7bd68
04 Item2: 9d7bd5c
05 Item3: 9d7bd50
06 Item4: 9d7bd44
07 ('After : ', '0xb77585acL')
08 True
09 Item1: 9d7bd68
10 Item2: 9d7bd5c
11 Item3: 9d7bd50
12 Item4: 9d7bd44
13 Item5: 9d7bd38
14 Item6: 9d7bd2c
复制代码
总的来说,写python代码时尽可能的多使用增强赋值语,因为它比普通赋值语句少了一次运算,而且在可能的情况下会执行原处(in-place)修改,执行起来也更快一些,也可以少打几个字
留个小问题:
上面加粗的“可能的情况”这几个字是什么意思,什么情况下会失败呢?可以把demo里的list改为integer,然后看看结果,然后思考list和integer这两种类型有什么不同?为什么会造成这种结果? Enjoy it!
欢迎光临 Chinaunix (http://bbs.chinaunix.net/)
Powered by Discuz! X3.2