由於底層的c實現,python中的指針問題也成爲了一個大問題,得好好研究
1) 共享引用
由於python中,萬物皆對象,所以賦值總是代表着引用的copy,很好的一個例子
- >>> X = [1, 2, 3]
- >>> L = ['a', X, 'b']
- >>> D = {'x':X, 'y':2}
- >>> L
- ['a', [1, 2, 3], 'b']
- >>> D
- {'y': 2, 'x': [1, 2, 3]}
- >>> X[1] = 'aha'
- >>> X
- [1, 'aha', 3]
- >>> L
- ['a', [1, 'aha', 3], 'b']
- >>> D
- {'y': 2, 'x': [1, 'aha', 3]}
有程序設計經驗的人很容易明白上面的代碼,當我們在L,D中使用X時,實際上是把[1, 2, 3]這個列表的地址放到了L,D中X的位置上,當[1, 2, 3]中元素改變時,地址並沒有變,所以L,D也跟着變。
- >>> s = 'abc'
- >>> l = [1, 2, s]
- >>> l
- [1, 2, 'abc']
- >>> s = 'def'
- >>> l
- [1, 2, 'abc']
這段代碼有人就該迷糊了,s不是指向的是一個字符串地址嗎,l中相應的位置也是這個地址啊,s改變了,爲什麼l不變?呵呵,原因就是字符串是不可遍的,當我們把'def'賦給s時,s所指向的地址就變了,而l中s的位置還是存的'abc'的地址,這就是l不變的原因。
還有一個有趣的例子
- >>> L = [1, 2]
- >>> X = L * 2
- >>> X
- [1, 2, 1, 2]
- >>> Y = [L] * 2
- >>> Y
- [[1, 2], [1, 2]]
- >>> L[1] = 'aha'
- >>> X
- [1, 2, 1, 2]
- >>> Y
- [[1, 'aha'], [1, 'aha']]
實際上X的效果類似[1, 2] + [1, 2],Y的效果類似[L] + [L] = [L, L],這回該明白了吧。
2)比較
java中比較有==,<=,>=,equals,comparaTo等等。python中比較是==,<=,>=,is,is not。當我們使用python的比較時,它會自動比較兩個對象中內部的數據結構。啥也不說了,例子是最好的teacher
- >>> L1 = [1, ('a', 3)]
- >>> L2 = [1, ('a', 3)]
- >>> L1 == L2
- True
- >>> L1 is L2
- False
- >>> L1 < L2
- False
- >>> L1 > L2
- False
- >>> L2[1] = ('a', 2)
- >>> L2
- [1, ('a', 2)]
- >>> L1 < L2
- False
- >>> L1 > L2
- True
3) 消除指針影響
對於向列表和字典那樣的可變類型來說,有時我們不需要指針式的引用(在java中,也有類似的需求),實際上解決起來很簡單,例子說明一切
- >>> L = [1, 2, 3]
- >>> M = ['x', L[:], 'y']
- >>> M
- ['x', [1, 2, 3], 'y']
- >>> L[1] = 'aha'
- >>> L
- [1, 'aha', 3]
- >>> M
- ['x', [1, 2, 3], 'y']