Python 字符串赋值
我看了一下python代码,其中字符串变量赋值如下所示:Python 字符串赋值,python,Python,我看了一下python代码,其中字符串变量赋值如下所示: var1 = var2[:] 我只是想知道以下两者之间的区别: var1 = var2 以下是我的实验: >>> original = "some text" >>> copy1 = original >>> copy2 = original[:] >>> original = "another text" >>> copy1 'some tex
var1 = var2[:]
我只是想知道以下两者之间的区别:
var1 = var2
以下是我的实验:
>>> original = "some text"
>>> copy1 = original
>>> copy2 = original[:]
>>> original = "another text"
>>> copy1
'some text'
>>> copy2
'some text'
更新:
这是一份完整的报告。此代码在密钥中搜索替换密码。
如果我删除“[:]”,这段代码将运行得非常慢。由于,这两段代码(在生成的对象中)通常没有区别。我们可以使用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
是一些可变的顺序对象,比如列表
,那么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 Chaudhary的答案。因为,两者之间通常没有差异(在生成的对象中)。我们可以使用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
是一些可变的顺序对象,比如列表
,那么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 Chaudhary的答案。
[:]
符号用于切片
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
[:]
符号用于切片
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
a[:]
与刚才的a
相同,id(a)==id(a[:])
,所以没有区别)
For list[:]返回其副本
a = [1, 2, 3]
id(a) == id(a[:])
>>> False
a[:]
与刚才的a
相同,id(a)==id(a[:])
,所以没有区别)
For list[:]返回其副本
a = [1, 2, 3]
id(a) == id(a[:])
>>> False
在链接到的完整代码中,
original
可能是列表,而不是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所述,在这种情况下,创建副本会有所不同。在链接到的完整代码中,有可能原始
是列表,而不是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所述,在这种情况下,创建副本会有所不同。请注意,在代码中,变量可以是列表,而不是字符串
请参见以下示例:
>>> a = [1,2,3]
>>> b = a
>>> b[0] = 'foo'
>>> a
['foo', 2, 3]
但是:
换句话说,在第一个示例中,对a
的引用保留在b
和changingb
changesa
中。使用切片表示法可以生成一个深度(1级)副本。请注意,在代码中,变量可以是列表
而不是字符串
请参见以下示例:
>>> a = [1,2,3]
>>> b = a
>>> b[0] = 'foo'
>>> a
['foo', 2, 3]
但是:
换句话说,在第一个示例中,对a
的引用保留在b
和changingb
changesa
中。使用切片表示法可以生成一个深度(1级)副本。我知道切片,但是我不知道为什么var1和var1之间有区别[:]@demasvar1[:]
在内部需要更多的步骤。我知道切片,但我不知道var1和var1[:]之间为什么有区别。@demasvar1[:]
在内部执行更多的步骤。你想知道[:]
是什么意思,还是想知道为什么它在这里似乎没有影响?你想知道[:]
是什么意思,还是想知道为什么它在这里似乎没有影响?你刚才把最后一句话弄错了:[:]
制作一个深拷贝(嗯,一个额外的层深)。这是复制字符串列表的一种非常方便的方法。你只是把最后一句话弄错了:[:]
做了一个深度复制(嗯,一个额外的层深度)。这是一种非常方便的复制字符串列表的方法。