![](/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.