我看一下python代码,其中字符串变量赋值如下:
var1 = var2[:]
我只是想知道它们之间有什么区别:
var1 = var2
这是我的实验:
>>> original = "some text"
>>> copy1 = original
>>> copy2 = original[:]
>>> original = "another text"
>>> copy1
'some text'
>>> copy2
'some text'
更新
这是一个完整的code。此代码搜索替换密码的密钥。 如果我删除'[:]',此代码将非常缓慢。
答案 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]
将返回从索引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
答案 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[:]
与a
,id(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