這是一則關(guān)于時間復(fù)雜度的思考引發(fā)的代碼瘦身案
由時間復(fù)雜度引出的思考與行動
之前看到這樣一段代碼:
class SequencePattern(object):
def __init__(self, sequence, frequent):
self.sequence = []
for s in sequence:
self._sequence.append(s)
self.frequent = frequent
初始化后self._sequence的值與sequence的值相等,這段代碼沒有語法錯誤俩由;但我非常好奇毒嫡,既然如此,為什么要通過for循環(huán)來給self._sequence賦值幻梯,增加時間復(fù)雜度兜畸,而不直接使用self._sequence = sequence來賦值?這樣寫有什么好處碘梢?
于是咬摇,按照我的想法修改代碼如下:
class SequencePattern(object):
def __init__(self, sequence, frequent):
self.sequence = sequence
self.frequent = frequent
我們來測試看看:
if __name__ == "__main__":
seq, freq = [1, 2, 3], 2
sp = SequencePattern(seq, freq)
sp.sequence.append(4)
print "sp.sequence:", sp.sequence
print "seq:", seq
得到如下結(jié)果:
sp.sequence: [1, 2, 3, 4]
seq: [1, 2, 3, 4]
我只想修改sp實(shí)例的sequence屬性,并不想修改變量seq煞躬,那么變量seq為什么也被修改了呢肛鹏?這就涉及到了Python對象的賦值逸邦、拷貝等相關(guān)概念
Python對象的賦值、深拷貝在扰、淺拷貝
python中的變量存儲的是變量的地址缕减,而非變量的值
- 賦值
復(fù)制原變量的地址,原變量與被賦值變量共享內(nèi)存地址芒珠,一個變量修改桥狡,另一個變量也會同時被修改
若a = [1,2,3],將a賦值給b皱卓,即b=a裹芝;這樣的賦值只是給對象[1,2,3]增加了一個引用,即a和b都指向?qū)ο骩1,2,3]的地址娜汁;若b.append(4)嫂易,則b=[1,2,3,4],且a=[1,2,3,4]
>>> a=[1,2,3]
>>> b=a
>>> b.append(4)
>>> print b
[1, 2, 3, 4]
>>> print a
[1, 2, 3, 4]
a.append(5)
>>> print b
[1, 2, 3, 4, 5]
>>> print a
[1, 2, 3, 4, 5]
- 淺拷貝copy.copy()
對于復(fù)合對象而言掐禁,淺拷貝會新開辟一塊地址存放復(fù)制來的數(shù)據(jù)炬搭,但淺拷貝只能復(fù)制原變量最外層對象的數(shù)據(jù),對于深層的對象穆桂,只能復(fù)制其地址宫盔,不能復(fù)制其數(shù)據(jù)
>>> c = [6,7,8]
>>> d = [9,10,c]
>>> print d
[9, 10, [6, 7, 8]]
>>> e = copy.copy(d) #淺拷貝
>>> print d
[9, 10, [6, 7, 8]]
>>> print e
[9, 10, [6, 7, 8]]
# 外層對象的修改,互不影響
>>> d[0]=11
>>> e[0]=12
>>> print d
[11, 10, [6, 7, 8]]
>>> print e
[12, 10, [6, 7, 8]]
>>> print id(d)
4400860696
>>> print id(e)
4400861056
#d, e共用深層對象c的地址享完,所以c被修改后灼芭,d,e都會被修改
>>> c.append(13)
>>> print d
[11, 10, [6, 7, 8, 13]]
>>> print e
[12, 10, [6, 7, 8, 13]]
- 深拷貝 copy.deepcopy()
復(fù)制原變量的所有數(shù)據(jù),原變量與被拷貝變量各自完全獨(dú)立般又,對一個變量的修改不會影響另一個變量
>>> f=copy.deepcopy(d) # f完全拷貝d的所有數(shù)據(jù)
>>> print d
[11, 10, [6, 7, 8, 13]]
>>> print f
[11, 10, [6, 7, 8, 13]]
#子對象的修改不影響新變量
>>> c.append(14)
>>> print d
[11, 10, [6, 7, 8, 13, 14]]
>>> print f
[11, 10, [6, 7, 8, 13]]
代碼瘦身
import copy
class SequencePattern(object):
def __init__(self, sequence, frequent):
self.sequence = copy.deepcopy(sequence)
self.frequent = copy.deepcopy(frequent)