字符串赋值

时间:2012-11-06 08:14:08

标签: python

我看一下python代码,其中字符串变量赋值如下:

var1 = var2[:]

我只是想知道它们之间有什么区别:

var1 = var2

这是我的实验:

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

更新

这是一个完整的code。此代码搜索替换密码的密钥。 如果我删除'[:]',此代码将非常缓慢。

5 个答案:

答案 0 :(得分:5)

由于interning,两者之间通常没有差异(在结果对象中)。我们可以使用is运算符检查两个变量是否指向同一个对象,与==运算符相比,检查对象的实际内存地址是否相同:

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

Interning是一种保存内存并加速不可变对象比较的机制,它的工作方式如下:在创建新的不可变之前,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的回答。

答案 1 :(得分:2)

[:]表示法用于切片,

a[m:n]将返回从索引mn-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

答案 2 :(得分: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 所述,在这种情况下创建副本会有所不同。

答案 3 :(得分: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级)副本。

答案 4 :(得分: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
相关问题