python中a+=b與a=a+b詳解

整體上講,a+=b是改變了a原始的值,而a=a+b是計算出a+b後,a在指向那個值。這個也跟a和b的類型有關。當a和b是int或者string不可改變的時候,兩者效果同樣。 python

>>> a=[1,2,3,4] 
>>> b=a 
>>> a+=[5] 
>>> a,b 
([1, 2, 3, 4, 5], [1, 2, 3, 4, 5])#a,b的「地址」同樣 
>>> a=[1,2,3,4] 
>>> b=a 
>>> a=a+[5]#a+[5]後有一個新地址,再使a指向這個新地址,所以a再也不是之前的a,而b仍是之前的那個a//b,因此b不變 
>>> a,b 
([1, 2, 3, 4, 5], [1, 2, 3, 4])



>>> a=[[1],[2]] 
>>> b=[] 
>>> b+=a[0:1]#這句將列表a中第一個元素的「指針」給了b[0],此時a[0]和b[0]是同樣的 
>>> a,b 
([[1], [2]], [[1]]) 
>>> b[0][0]='change'#b[0]就至關於取到了a裏面的第一個元素,也是一個列表。b[0][0]也就定位到了a[0][0],對應的內容就是1 
>>> a,b 
([['change'], [2]], [['change']])#所以b[0][0]改了,a[0][0],也相應的改了。 
>>> id(b[0][0]);id(a[0][0])#不用說,地址同樣 
11534048 
11534048 
>>> id(b[0]);id(a[0]) 
12903888 
12903888 
>>> b[0],a[0] 
(['change'], ['change']) 
>>> b[0]='another'#這裏應該是有一塊新地址,再讓b[0]指向這個新地址。  
>>> a,b 
([['change'], [2]], ['another'])# 所以a中的值沒有變
>>> a[0] 
['change'] 
>>> id(b[0]);id(a[0]) #此時,b[0]跟a[0]的地址不同
13056672 
12903888




>>> a=[1,2]#初始化a,爲列表[1,2]
>>> a+='3' #直接+=方式,追加元素」3」
>>> a
[1, 2, '3']
>>> a+=['4'] #追加列表,比上面的‘3’ 多了個[]。
>>> a
[1, 2, '3', '4']#一樣能追加成功,怎麼感受有無[]沒有區別啊?
>>> a+'5'#固然,直接+字符串,就拋異常了。
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: can only concatenate list (not "str") to list




要解釋這個問題,看看python裏的源碼便可。知道+=這個操做其實是調用了__iadd__方法(能夠用此重載操做符,stackoverflow上有這個重載+=的問題).而在__iadd__方法內部,是直接調用了extend()方法,而a.extend(‘3’)和a.extend([‘3’])沒有區別嗎?表面上看來是沒有區別的。 數組


>>> a=[1,2]
>>> a.extend('3')
>>> a
[1, 2, '3']
>>> a.extend(['3'])
>>> a
[1, 2, '3', '3']
>>>



而實際上,在extend(arg)方法內部,又去調用了append方法 app


def extend(self, values):
        for v in values:
            self.append(v)



這樣,’3’ 和 [‘3’] 就沒區別被append進去了。字符串會被看成數組append進去。 spa


>>> a
[1, 2, '3', '3']
>>> a.extend('abc')
>>> a
[1, 2, '3', '3', 'a', 'b', 'c']
>>> a.extend(['23','ab'])
>>> a
[1, 2, '3', '3', 'a', 'b', 'c', '23', 'ab']





http://stackoverflow.com/questions/2347265/why-does-behave-unexpectedly-on-lists
指針

http://stackoverflow.com/questions/6951792/python-a-b-not-the-same-as-a-a-b
相關文章
相關標籤/搜索