2012-11-06 97 views
1

我看看Python代碼,其中字符串變量賦值的樣子:字符串賦值

var1 = var2[:] 

我只是想知道是什麼樣的區別:

var1 = var2 

這裏是我的實驗:

>>> original = "some text" 
>>> copy1 = original 
>>> copy2 = original[:] 
>>> original = "another text" 
>>> copy1 
'some text' 
>>> copy2 
'some text' 

更新:

這是一個完整的code。此代碼搜索替代密碼的密鑰。 如果我刪除'[:]'這個代碼將非常緩慢地工作。

+0

你想知道'[:]'是什麼意思,或者你想知道爲什麼它在這裏似乎沒有什麼區別? – erikbwork

回答

5

由於interning,兩者之間往往沒有區別(在結果對象中)。我們可以檢查兩個變量是否指向同一對象使用is運營商,這相較於==操作檢查wheter對象的實際內存地址是相同的:

>>> a = "foo" 
>>> b = a 
>>> a is b 
True 
>>> c = a[:] 
>>> a is c 
True 

實習是用於保存機制內存,並加速了不可變對象的比較,它的工作原理如下:在創建一個新的不可變的對象之前,python會檢查是否存在一個完全相同的不可變對象。如果是這樣,它只是使用對現有對象的引用。它可以做到沒有傷害,因爲沒有辦法改變不可變的。這就是爲什麼甚至是兩個獨立創建的字符串可能指向同一個對象:

>>> a = "foo" 
>>> b = "foo" 
>>> a is b 
True 

但如果var2是一些可變連續的物體,比如list,然後var2[:]將是var2淺拷貝,以便在修改一個不會影響另一個。

>>> a = list("foo") 
>>> a 
['f', 'o', 'o'] 
>>> b = a 
>>> b is a 
True 
>>> c = a[:] 
>>> c is a 
False 
>>> b.pop() 
'o' 
>>> a 
['f', 'o'] 
>>> b 
['f', 'o'] 
>>> c 
['f', 'o', 'o'] 

對於完整的圖片,也閱讀Ashwini Chaudharys的答案。

+0

我已添加完整的代碼並添加其他信息。 – demas

2

[:]符號用於切片,

a[m:n]將返回字符從指數m開始高達n-1,如果沒有獲得通過,返回整個字符串返回。

In [1]: a="foobar" 

In [2]: a[:]   #this is equal to a only as nothing to passed to slicing 
Out[2]: 'foobar' 

In [3]: a[1:]   #return everything after index 1 
Out[3]: 'oobar' 

In [4]: a[:1]   #return everything before 1st index 
Out[4]: 'f' 

In [5]: a[:-1]  #return everything before the last character 
Out[5]: 'fooba' 

b=a[:]b=a之間的區別是,B = A花費較少的步數內:

In [7]: def func1(): 
    ...:  a="foo" 
    ...:  b=a 
    ...:  

In [8]: def func2(): 
    ...:  a="foo" 
    ...:  b=a[:] 
    ...:  

In [9]: dis.dis(func1) 
    2   0 LOAD_CONST    1 ('foo') 
       3 STORE_FAST    0 (a) 

    3   6 LOAD_FAST    0 (a) 
       9 STORE_FAST    1 (b) 
      12 LOAD_CONST    0 (None) 
      15 RETURN_VALUE   

In [10]: dis.dis(func2) 
    2   0 LOAD_CONST    1 ('foo') 
       3 STORE_FAST    0 (a) 

    3   6 LOAD_FAST    0 (a) 
       9 SLICE+0    
      10 STORE_FAST    1 (b) 
      13 LOAD_CONST    0 (None) 
      16 RETURN_VALUE 

timeit

In [11]: %timeit func1() 
1000000 loops, best of 3: 336 ns per loop 

In [12]: %timeit func2() 
1000000 loops, best of 3: 397 ns per loop 
+0

我知道切片,但我不知道爲什麼var1和var1之間有區別[:] – demas

+0

@demas'var1 [:]'在內部需要更多步數。 –

0

a[:]相同只是aid(a) == id(a[:]),所以沒有區別)

a = 'Convert an integer number to a binary string Convert an integer number to a binary' 
id(a) == id(a[:]) 
>>> True 

對於列表[:]返回它的副本。

a = [1, 2, 3] 
id(a) == id(a[:]) 
>>> False 
1

在您鏈接到完整的代碼,有一個original是一個list的可能性,而不是一個str

parentkey,parentscore = startkey or list('ABCDEFGHIJKLMNOPQRSTUVWXYZ'),-99e99 

然後

child = parentkey[:] 
# swap two characters in the child 
child[a],child[b] = child[b],child[a] 

正如lazyr提到,創建一個副本將在這種情況下有所作爲。

1

請注意,在您的代碼中,變量可以是list而不是字符串。

參見下面的示例:

>>> a = [1,2,3] 
>>> b = a 
>>> b[0] = 'foo' 
>>> a 
['foo', 2, 3] 

但:

>>> a = [1,2,3] 
>>> b = a[:] 
>>> b[0] = 'foo' 
>>> a 
[1, 2, 3] 

換句話說,在第一實施例中,參考到a是保存在b和改變b改變a。使用切片符號[:]可生成深層(1層)的副本。

+0

你剛剛得到了最後一個句子:'[:]'產生了一個**深**副本(好一層深)。這是一個非常方便的方法來複制,比如說一個字符串列表。 –