2012-11-06 180 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

你刚刚得到了最后一个句子:'[:]'产生了一个**深**副本(好一层深)。这是一个非常方便的方法来复制,比如说一个字符串列表。 –