![](/img/trans.png)
[英]set has no order but random.choice( list(set) ) is unstable given random seed
[英]Random seed for order of elements in Python's Set to List conversion
我在 Jupyter notebook 中执行一些代码并注意到每次运行它时,output 都是不同的,尽管我的程序中没有明确地加入随机性。
我将它缩小到一行,从列表中删除所有重复的元素。
l = list(set(l))
我注意到两件事:
如果我在同一个 Jupyter kernel 中重新运行相同的代码,对于 l,我总是得到相同的 output,但是
如果我打开另一个笔记本,我会得到一个不同的 output。
是否有某种隐藏的随机种子用于给定 kernel 的集合 -> 列表转换? 它是如何工作的,如果我想从上面的代码中得到确定性的 output,我会怎么做?
set
功能与dict
几乎相同,以对象的hash
作为键。 大多数对象(在 CPython 中)的默认__hash__
函数依赖于它们的id
,而后者又依赖于它们在内存中的地址。
新内核意味着对象具有不同的地址,这意味着不同的id
、不同的hash
以及集合给出的迭代器的不同顺序。
这是依赖于实现的,所以你不能依赖它,我只能说 CPython,到目前为止,以这种方式工作。 您可以依赖的set
不是(有用)订购的。
如果您需要订购,请保留清单和套餐。 如果您想在保留顺序的同时删除重复,则可以使用以下方法:
def could_add(s, x):
if x in s:
return False
else:
s.add(x)
return True
seen = set()
[x for x in l if could_add(seen, x)]
(虽然我完全同意 Barmar 的评论——如果顺序很重要,它们应该是可排序的。)
您可以使用OrderedDict
而不是set
来从列表中删除所有重复的元素并保持其顺序。 如果您使用 python>=3.6, dict
也会保持其顺序与OrderedDict
相同。
# python < 3.6
from collections import OrderedDict
res = list(OrderedDict.fromkeys(yourlist))
# pyton >= 3.6
res = list(dict.fromkeys(yourlist))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.