Set Popping (Python)

别来无恙 提交于 2021-02-18 21:06:51

问题


Lets say you have a set:

foo = {1, 2, 3, 4, 5}

In the book I am currently reading, Pro Python, it says that using foo.pop()will pop an arbitrary number from that selection. BUT...When I try it out, it pops 1, then 2, then 3...Does it do it arbitrarily, or is this just a coincidence?


回答1:


The reason it says it is arbitrary is because there is no guarantee about the ordering it will pop out. Since you just created the set, it may be storing the elements in a "nice" order, and thus .pop() happens to return them in that order, but if you were to mutate the set, that might not continue to hold.

Example:

>>> foo = set()
>>> foo.add(-3)
>>> foo.add(-1)
>>> foo.add(2)
>>> foo.pop()
2
>>> foo.pop()
-3



回答2:


Set and dictionaries are implemented using hash tables. They are unordered collections, meaning that they have no guaranteed order.

The order you're seeing is a non-guaranteed implementation detail. In CPython, the hash value for an integer is the integer itself:

>>> [hash(i) for i in range(10)]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

That implementation detail causes the integers to appear ordered in your set. Other sets would be semi-ordered, {5, 6, 7, 8, 9} appears as set([8, 9, 5, 6, 7]).

In contrast, other datatypes such as str have different hash functions and will appear to be more scrambled. For example:

# Example of scrambling str objects in a 64-bit build
>>> {'red', 'green', 'blue'}
set(['blue', 'green', 'red'])

The set.pop method pops off entries left-to-right. That is also a non-guaranteed implementation detail.

The short answer to your question is Yes, the ordering is arbitrary but No, what you saw wasn't just a coincidence either, rather it was an interesting non-guaranteed implementation detail.

Hope this clears-up the mystery for you :-)



来源:https://stackoverflow.com/questions/9848693/set-popping-python

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!