使用id()时[]和list()有区别吗?
Is there a difference between [] and list() when using id()?
有人可以解释一下吗?
为什么id一样,list却不一样?
>>> [] is []
False
>>> id([]) == id([])
True
创建列表有区别吗?
>>> id(list()) == id(list())
False
>>> id([]) == id([])
True
为什么会这样?我得到两个不同的列表。为什么不只有一个,或者三个或更多?
>>> [].__repr__
<method-wrapper '__repr__' of list object at 0x7fd2be868128>
>>> [].__repr__
<method-wrapper '__repr__' of list object at 0x7fd2be868170>
>>> [].__repr__
<method-wrapper '__repr__' of list object at 0x7fd2be868128>
>>> [].__repr__
<method-wrapper '__repr__' of list object at 0x7fd2be868170>
你用错了id()
。 id([])
获取立即丢弃 的对象的内存 ID。毕竟,一旦 id()
完成后,就不再引用它了。所以下次你使用 id([])
Python 时,你会发现有机会重新使用内存,你瞧,那些地址确实是一样的。
但是,这是一个实现细节,您不能依赖它,它并不总是能够重用内存地址。
请注意,id()
值仅在对象的生命周期内是唯一的,请参阅 documentation:
This is an integer which is guaranteed to be unique and constant for this object during its lifetime. Two objects with non-overlapping lifetimes may have the same id()
value.
(大胆强调我的)。
id(list())
无法重新使用内存位置可能是由于将当前帧压入堆栈以调用函数,然后在 list()
调用 returns.
[]
和list()
都产生一个new空列表对象;但您需要先创建对这些单独列表的引用(此处 a
和 b
):
>>> a, b = [], []
>>> a is b
False
>>> id(a) == id(b)
False
>>> a, b = list(), list()
>>> a is b
False
>>> id(a) == id(b)
False
当您使用 [].__repr__
时也会发生同样的情况。 Python 交互式解释器有一个特殊的全局名称,_
,您可以使用它来引用最后产生的结果:
>>> [].__repr__
<method-wrapper '__repr__' of list object at 0x10e011608>
>>> _
<method-wrapper '__repr__' of list object at 0x10e011608>
这会创建一个额外的引用,因此 __repr__
方法,以及您为其创建的空列表 仍然被认为是活动的 。内存位置未释放且不可用于您创建的下一个列表。
但是再次执行 [].__repr__
,Python 现在将 _
绑定到那个新的方法对象。突然之前的 __repr__
方法不再被任何东西引用,可以被释放,列表对象也是如此。
第三次执行 [].__repr__
时,第一个内存位置再次可供重用,因此 Python 就是这样做的:
>>> [].__repr__ # create a new method
<method-wrapper '__repr__' of list object at 0x10e00cb08>
>>> _ # now _ points to the new method
<method-wrapper '__repr__' of list object at 0x10e00cb08>
>>> [].__repr__ # so the old address can be reused
<method-wrapper '__repr__' of list object at 0x10e011608>
您永远不会创建两个以上的列表;上一个(仍由 _
引用)和当前一个。如果您想查看更多内存位置,请使用变量添加另一个引用。
有人可以解释一下吗?
为什么id一样,list却不一样?
>>> [] is []
False
>>> id([]) == id([])
True
创建列表有区别吗?
>>> id(list()) == id(list())
False
>>> id([]) == id([])
True
为什么会这样?我得到两个不同的列表。为什么不只有一个,或者三个或更多?
>>> [].__repr__
<method-wrapper '__repr__' of list object at 0x7fd2be868128>
>>> [].__repr__
<method-wrapper '__repr__' of list object at 0x7fd2be868170>
>>> [].__repr__
<method-wrapper '__repr__' of list object at 0x7fd2be868128>
>>> [].__repr__
<method-wrapper '__repr__' of list object at 0x7fd2be868170>
你用错了id()
。 id([])
获取立即丢弃 的对象的内存 ID。毕竟,一旦 id()
完成后,就不再引用它了。所以下次你使用 id([])
Python 时,你会发现有机会重新使用内存,你瞧,那些地址确实是一样的。
但是,这是一个实现细节,您不能依赖它,它并不总是能够重用内存地址。
请注意,id()
值仅在对象的生命周期内是唯一的,请参阅 documentation:
This is an integer which is guaranteed to be unique and constant for this object during its lifetime. Two objects with non-overlapping lifetimes may have the same
id()
value.
(大胆强调我的)。
id(list())
无法重新使用内存位置可能是由于将当前帧压入堆栈以调用函数,然后在 list()
调用 returns.
[]
和list()
都产生一个new空列表对象;但您需要先创建对这些单独列表的引用(此处 a
和 b
):
>>> a, b = [], []
>>> a is b
False
>>> id(a) == id(b)
False
>>> a, b = list(), list()
>>> a is b
False
>>> id(a) == id(b)
False
当您使用 [].__repr__
时也会发生同样的情况。 Python 交互式解释器有一个特殊的全局名称,_
,您可以使用它来引用最后产生的结果:
>>> [].__repr__
<method-wrapper '__repr__' of list object at 0x10e011608>
>>> _
<method-wrapper '__repr__' of list object at 0x10e011608>
这会创建一个额外的引用,因此 __repr__
方法,以及您为其创建的空列表 仍然被认为是活动的 。内存位置未释放且不可用于您创建的下一个列表。
但是再次执行 [].__repr__
,Python 现在将 _
绑定到那个新的方法对象。突然之前的 __repr__
方法不再被任何东西引用,可以被释放,列表对象也是如此。
第三次执行 [].__repr__
时,第一个内存位置再次可供重用,因此 Python 就是这样做的:
>>> [].__repr__ # create a new method
<method-wrapper '__repr__' of list object at 0x10e00cb08>
>>> _ # now _ points to the new method
<method-wrapper '__repr__' of list object at 0x10e00cb08>
>>> [].__repr__ # so the old address can be reused
<method-wrapper '__repr__' of list object at 0x10e011608>
您永远不会创建两个以上的列表;上一个(仍由 _
引用)和当前一个。如果您想查看更多内存位置,请使用变量添加另一个引用。