【问题标题】:Why Python allocates new id to list, tuples, dict even though having same values?为什么即使具有相同的值,Python 也会为 list、tuples、dict 分配新的 id?
【发布时间】:2016-02-18 09:42:37
【问题描述】:
x1 = 5
y1 = 5
x2 = 'Hello'
y2 = 'Hello'
x3 = [1,2,3]
y3 = [1,2,3]
print(x1 is y1)
print(x2 is y2)
print(x3 is y3)

输出

True
True
False

为什么 Python 会为 y3 分配一个不同的 id,而不是 x3

这里的x3y3 是列表,但Python 对元组和字典也是如此。我还想知道 Python 在哪里还有将新 id 分配给具有相同值的变量的相同行为,为什么会这样?

【问题讨论】:

  • 红利:print(253 is 252+1)print(258 is 257+1)
  • 奖励奖励:print("%s%s" % ("Hello" * 100,"World" * 100) is "Hello" * 100 + "World" * 100)
  • 结论:将is 用于is None,但仅此而已,除非您知道自己在做什么以及为什么要这样做。
  • stackoverflow.com/questions/306313/…基本cpython所做的是将所有整数从0保存到NSMALLPOSINTS以优化内存使用。亲自尝试[sys.getrefcount(x) for x in range(300)]

标签: python


【解决方案1】:

因为否则会发生这种情况:

x3 = [1,2,3]
y3 = [1,2,3]

x3[0] = "foo"
x3[0] == y3[0] # Does NOT happen!

其实

x3[0] != y3[0]

这是一件好事™。如果x3y3 相同,那么更改一个也会更改另一个。这通常不是预期的。

另请参阅 when does Python allocate new memory for identical strings? 为什么字符串的行为不同。

另外,如果您想比较,请使用==

【讨论】:

  • 您的意思是说,如果 x3 和 y3 具有相同的 id,那么 x3[0]==y3[0] 将是 True 即使 x3[0]='foo' 和 y3[0]= 1 个?
  • 我同意你的回答,但你的“事实上”让我很困惑。什么意思?
  • 事实上,改变x3[0]改变y3[0],它们是!=。他们不是==
  • 通常“不是==”等价于“!=”,所以我仍然不认为它具有说明性。对不起,也许我在挑剔,因为我试图在两行之间阅读,我不应该......
【解决方案2】:

Tichodroma 说得非常好。但是,如果您想为具有相同值的列表、字典等(如果您想为同一个对象使用不同的名称)使用相同的 id(),则可以这样做:

>>> x3 = y3 = [1,2,3]
>>> print(x3 is y3)
True

在这种情况下 x3 和 y3 引用内存中的同一个列表对象。所以,如果你改变其中任何一个,另一个也会改变。

>>> x3[1] = 10
>>> y3
[1, 10, 3]
>>> x3
[1, 10, 3]

奖金:

如果整数值相同,它们并不总是具有相同的id。看看here

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

测试:

>>> n = 256
>>> m = 256
>>> n is m
True
>>> n = 257
>>> m = 257
>>> n is m
False
>>> 

一个更有趣的测试(看图!):

>>> 2**8 is 2**8
True
>>> 2**9 is 2**9
False

P.S.:我正在运行 python 3.4。来自 docs 的引用是针对 python 2.7 的(我没有找到 python 3.4 的等价物)。但我仍然在我正在运行的 python 3.4 中得到类似的输出。因此,对于 python 2.7 所说的 当前实现 似乎对 python 3.4 仍然有效。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-10-03
    • 1970-01-01
    • 2012-02-19
    • 2015-03-09
    • 2022-07-22
    • 2019-04-03
    • 1970-01-01
    • 2016-01-03
    相关资源
    最近更新 更多