搞乱别名

时间:2011-03-10 20:40:33

标签: python aliasing

我有以下代码按预期工作:

a = [1, 2, 3, 4]
b = a

>>> b is a
True

如果我稍微更改它仍然有效:

a = [1, 2, 3, 4]
b = a[2] * 2

>>> b is a[2] * 2
True

现在出现问题:

a = [1, 2, 3, 4]
b = a * 2

>>> b is a * 2
False    

有人可以向我解释为什么这会返回False,而b is a[2] * 2会返回True吗?

3 个答案:

答案 0 :(得分:4)

a是列表时,a * 2会创建一个新的列表实例。如果您拨打a * 2两次,则会创建两个新的列表实例 - 这就是b is a * 2产生False的原因。

True获得b is a[2] * 2的原因是CPython的优化,它缓存小整数。由于整数在Python中是不可变的,因此如果获得新实例或缓存实例并不重要,对于小整数,如果再次使用相同的整数,Python将返回缓存版本。也试试

>>> a = [1, 2, 300, 4]
>>> b = a[2] * 2
>>> b is a[2] * 2
False

答案 1 :(得分:2)

相同的列表在比较is时不等效,除非它们引用相同的列表。仅仅因为列表具有相同的值并不意味着它们在内存中引用相同的列表。

,例如,

>>> a = [1,2,3]
>>> id(a) # memory location list a references
161267628
>>> b = [1,2,3]
>>> id(b) # memory location list b references, a different memory location than list a
161276396
>>> a == b 
True
>>> a is b
False
>>> c = a # by this method of assignment; c points to the same point that a does;
# hence changes to a and changes to c, will change both.
>>> id(c) # memory location that c references; this is the same as where a points.
161267628
>>> a is c
True
>>> c.append(4)
>>> print a
[1, 2, 3, 4]
>>> print b
[1, 2, 3]
>>> print c
[1, 2, 3, 4]
>>> d = a[:] # this just copies the values in a to d.  
>>> id(d)
161277036

这是有意义的,它们指向不同的内存位置,因为如果您可能想要更改第一个列表(如将4追加到结尾a)而不修改b如果ab指向内存中的相同位置,则无法实现。

答案 2 :(得分:0)

a * 2构造一个新列表,而一个整数与自身具有同一性。

>>> type(a[2] * 2)
<type 'int'>
>>> type(a * 2)
<type 'list'>