Python名称/绑定 - 为什么不是所有相同长度的列表"相同列表"?

时间:2017-02-08 00:29:50

标签: python pointers

我知道Python中有很多关于指针和引用(或者更确切地说:名称和绑定!)的资源,但我很难理解最后一点:

如果a = 1b = 1,那么我得到的就是他们两个都被绑定了#39;确切地说是1并且具有相同的id()(因此,我认为是内存地址)。如果你设置:

我也会得到
a = [1, 2, 4]
b = a
b[0] = 45
# a is now [45, 2, 4]

因为ab绑定到同一个列表(对象),一个更改导致另一个更改。同样,a[0]b[0]是同一个对象。该列表包含具有不同ID的其他对象 - 也就是列表标识未绑定到其内容。

好。到现在为止还挺好。我可以接受,有“未出生的”'列表和数字在等待初始化时浮动(只有一次!),并且Python会在我们需要它们时为它们分配一个内存空间。为什么然后,如果我这样做:

d = [1, 2]
e = [145, 7]
# id(d) and id(e) are not the same?!

难道不存在Python中只有一个2元素列表吗?这对我来说是一致的(然后只有一个1,一个2,一个145 ......等等)。

任何解释都会受到赞赏 - 包括那些将它与指针联系起来的解释(因为我对内存管理级别的决策也有些神秘感,但我认为这是Python的关注&# 39;执行模型而不是我!)

2 个答案:

答案 0 :(得分:3)

你被int的CPython中的优化所误导,即int-caching。请参阅this着名问题。记录在案here

  

当前实现为所有实体保留了一个整数对象数组   -5到256之间的整数,当你在该范围内创建一个int时   实际上只是返回对现有对象的引用。

在几乎所有其他实例中,使用文字创建新对象。实际上,在该范围之外使用int,您将看到正常行为:

>>> a = 100000
>>> b = 100000
>>> id(a)
4322630608
>>> id(b)
4322630640
>>> c = a
>>> id(a) == id(b)
False
>>> id(a) == id(c)
True

我几乎每天都要重复这一点,但在Python中分配从不复制

答案 1 :(得分:1)

=是一项任务。

[1, 2, 3]10是对象。

如果你写10[1, 2, 3] python会创建一个对象。如果您不使用任务,垃圾收集器将删除它。但是如果你这样做,python会将指向新创建的对象的指针分配给给定的名称/变量,即:

a = [1, 2]

接下来,当您将变量分配给另一个变量时,python将从第一个变量复制指针,即:

b = a

b现在包含指向与a相同的对象的指针。但是任何新创建的对象,即使内容相同,也是一个不同的对象。这样:

id(a) != id([1, 2])

现在,根据实施情况(所以它可以随时更改而你不应该依赖它)可能会有一个"快捷方式"为了提高速度,默认情况下可能会创建表示某些常用值的对象。这就是为什么在某些实施id(1) == id(1)上,但令人困惑的是id(5555) != id(5555)