Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a difference between [] and list() when using id()?

Can somebody explain the following?

Why is the id the same, but the lists are different?

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

Is there difference in list creation?

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

Why is this happening? I get two different lists. Why not only one, or three or more?

>>> [].__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>
like image 970
Vlad Okrimenko Avatar asked Nov 26 '16 17:11

Vlad Okrimenko


People also ask

What is the difference between [] and list ()?

list is a global name that may be overridden during runtime. list() calls that name. [] is always a list literal.

Are list () and [] the same Python?

Technically speaking, one is a function that returns an object casted to a list, and the other is the literal list object itself. Kinda like int(0) vs 0 . In practical terms there's no difference. I'd expect [] to be faster, because it does not involve a global lookup followed by a function call.

What is ID of list in Python?

The id() function returns a unique id for the specified object. All objects in Python has its own unique id. The id is assigned to the object when it is created.


Video Answer


1 Answers

You used id() wrong. id([]) takes the memory id of an object that is discarded immediately. After all, nothing is referencing it anymore once id() is done with it. So the next time you use id([]) Python sees an opportunity to re-use the memory and lo and behold, those addresses are indeed the same.

However, this is an implementation detail, one you can't rely on, and it won't always be able to reuse the memory address.

Note that id() values are only unique for the lifetime of the object, see the 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.

(Bold emphasis mine).

That id(list()) can't re-use the memory location is probably due to the extra heap mutations caused by pushing the current frame on the stack to call a function, then popping it again when the list() call returns.

Both [] and list() produce a new empty list object; but you need to first create references to those separate lists (here a and 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

The same happens when you used [].__repr__. The Python interactive interpreter has a special global name, _, that you can use to reference the last result produced:

>>> [].__repr__
<method-wrapper '__repr__' of list object at 0x10e011608>
>>> _
<method-wrapper '__repr__' of list object at 0x10e011608>

That creates an extra reference, so the __repr__ method, and by extension, the empty list you created for it, are still considered active. The memory location is not freed and not available for the next list you create.

But executing [].__repr__ again, Python now binds _ to that new method object. Suddenly the previous __repr__ method is no longer referenced by anything and can be freed, and so is the list object.

The third time you execute [].__repr__ the first memory location is available again for reuse, so Python does just that:

>>> [].__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>

You never create more than two lists; the previous one (still referenced by _) and the current one. If you wanted to see more memory locations, use variables to add another reference.

like image 160
Martijn Pieters Avatar answered Oct 09 '22 21:10

Martijn Pieters