为什么 Python 的 set() 在某些情况下对列表进行排序?
Why is Python's set() sorting a list in some cases?
我对这个例子中 Python 的 set()
的行为感到困惑:
random_number_list = [randint(1, 10) for _ in range(10)]
# This will be sorted!
unique_numbers = set(random_number_list)
print(
f"random_number_list/unique_numbers with same upper bound for randint() and range():\n{random_number_list=}\n{unique_numbers=}\n"
)
random_number_list = [randint(1, 100) for _ in range(10)]
# This will not be sorted.
unique_numbers = set(random_number_list)
print(
f"random_number_list/unique_numbers with different upper bound for randint() and range():\n{random_number_list=}\n{unique_numbers=}\n"
)
如果列表的长度和 randint()
的上限相同,则 set()
似乎正在对 random_number_list
进行排序:
➜ ch-2 python --version
Python 3.10.0
➜ ch-2 python find_k_smallest.py
random_number_list/unique_numbers with same upper bound for randint() and range():
random_number_list=[10, 1, 2, 5, 5, 7, 8, 8, 2, 8]
unique_numbers={1, 2, 5, 7, 8, 10}
random_number_list/unique_numbers with different upper bound for randint() and range():
random_number_list=[35, 1, 17, 26, 17, 74, 26, 11, 44, 13]
unique_numbers={1, 35, 74, 11, 44, 13, 17, 26}
docs状态:
A set object is an unordered collection of distinct hashable objects.
这是怎么回事?为什么 set()
在某些情况下而不是其他情况下对 random_number_list
进行排序?
编辑 这些问题都没有解决我的问题:
- Does Python have an ordered set?
实际回答你的问题。集合的许多实现使用类似于哈希表的实现。根据该哈希值对项目进行哈希处理并放入“数组”中。
请注意,对于小整数,hash(x) == x。所以 1 将进入插槽 1,2 将进入插槽 2,3 将进入插槽 3,依此类推。然后当读取元素时,您将真正对元素进行排序。
但是,如果您的整数大于数组大小,则它们在数组中的位置将以数组大小为模。它们将不再排序。
同样,我还没有真正查看 Python 实现。这只是对可能发生的事情的可能解释。
“无序”并不意味着“未排序”。这意味着没有尝试提供任何特定的命令;从实施中掉下来的顺序可能是也可能不是排序顺序。
您在评论中写道:
I'm curious as to why set()
is ordering its members sometimes when the size of the list
is related to the bounds of randint()
.
这是一个应用程序不应该关注的实现细节,即使在 Python 3.7(和 3.10)中,set
也是 documented as "unordered collection[s]". You can look up, for example, the source code of CPython to find out how set
s are implemented in CPython。
另请参阅:
- Why does Python print a set of numbers as ordered
我对这个例子中 Python 的 set()
的行为感到困惑:
random_number_list = [randint(1, 10) for _ in range(10)]
# This will be sorted!
unique_numbers = set(random_number_list)
print(
f"random_number_list/unique_numbers with same upper bound for randint() and range():\n{random_number_list=}\n{unique_numbers=}\n"
)
random_number_list = [randint(1, 100) for _ in range(10)]
# This will not be sorted.
unique_numbers = set(random_number_list)
print(
f"random_number_list/unique_numbers with different upper bound for randint() and range():\n{random_number_list=}\n{unique_numbers=}\n"
)
如果列表的长度和 randint()
的上限相同,则 set()
似乎正在对 random_number_list
进行排序:
➜ ch-2 python --version
Python 3.10.0
➜ ch-2 python find_k_smallest.py
random_number_list/unique_numbers with same upper bound for randint() and range():
random_number_list=[10, 1, 2, 5, 5, 7, 8, 8, 2, 8]
unique_numbers={1, 2, 5, 7, 8, 10}
random_number_list/unique_numbers with different upper bound for randint() and range():
random_number_list=[35, 1, 17, 26, 17, 74, 26, 11, 44, 13]
unique_numbers={1, 35, 74, 11, 44, 13, 17, 26}
docs状态:
A set object is an unordered collection of distinct hashable objects.
这是怎么回事?为什么 set()
在某些情况下而不是其他情况下对 random_number_list
进行排序?
编辑 这些问题都没有解决我的问题:
- Does Python have an ordered set?
实际回答你的问题。集合的许多实现使用类似于哈希表的实现。根据该哈希值对项目进行哈希处理并放入“数组”中。
请注意,对于小整数,hash(x) == x。所以 1 将进入插槽 1,2 将进入插槽 2,3 将进入插槽 3,依此类推。然后当读取元素时,您将真正对元素进行排序。
但是,如果您的整数大于数组大小,则它们在数组中的位置将以数组大小为模。它们将不再排序。
同样,我还没有真正查看 Python 实现。这只是对可能发生的事情的可能解释。
“无序”并不意味着“未排序”。这意味着没有尝试提供任何特定的命令;从实施中掉下来的顺序可能是也可能不是排序顺序。
您在评论中写道:
I'm curious as to why
set()
is ordering its members sometimes when the size of thelist
is related to the bounds ofrandint()
.
这是一个应用程序不应该关注的实现细节,即使在 Python 3.7(和 3.10)中,set
也是 documented as "unordered collection[s]". You can look up, for example, the source code of CPython to find out how set
s are implemented in CPython。
另请参阅:
- Why does Python print a set of numbers as ordered