Python中的元组与列表对象

5 投票
3 回答
626 浏览
提问于 2025-04-16 06:55

有人能给我解释一下这个吗?

>>> [] is []
False
>>> () is ()
True
>>> (1,) is (1,)
False

我知道在比较值的时候应该用“==”而不是“is”,我只是想知道为什么要这样做?

3 个回答

2

可以这样理解:在你提到的第一个例子中,对于像元组这样的不可变对象,如果它们是完全相同的,Python的实现可以安全地共享这些对象:

>>> a = ()
>>> b = ()
>>> a is b
True

现在考虑一下:

>>> a = []
>>> b = []
>>> a.append("foo")
>>> print a,b
['foo'] []

在这种情况下,a和b不可能是同一个对象,因为修改a不应该影响b。

在你最后的例子中,你又回到了不可变的元组。Python的实现是允许将它们视为同一个对象,但并不是必须这样做。在这个例子中,它并没有这样做(这基本上是一个空间和时间的权衡——如果你的程序中使用了很多(1,)这样的元组,如果它们被共享的话,可以节省内存,但这会增加运行时的开销,因为需要判断某个元组是否是可以共享的(1,))。

3

在通过ID进行比较时要小心。如果一个对象被垃圾回收了,它的ID可能会被重新使用!

>>> id([])==id([])
True

或者甚至

>>> id([1,2,3])==id(["A","B","C"])
True
10

is 是用来判断对象的身份的。也就是说,它是在问:左边和右边是不是同一个对象?

在这些情况下,通常这些对象是不同的(因为你有六个不同的字面量)。不过,空的元组是同一个对象,这是因为实现上的一些优化。正如你所提到的,你不应该依赖这种行为。

需要注意的是,可变对象是不能被优化成同一个对象的,这意味着第一个判断一定是假的。

撰写回答