如果我有兩個相同的集合,意思是a == b
給我True
,它們是否具有相同的迭代順序?我試過了,它的工作原理:Python中集合的迭代順序
>>> foo = set("abc")
>>> bar = set("abc")
>>> zip(foo, bar)
[('a', 'a'), ('c', 'c'), ('b', 'b')]
我的問題是,我很幸運,還是這種行爲有保證?
如果我有兩個相同的集合,意思是a == b
給我True
,它們是否具有相同的迭代順序?我試過了,它的工作原理:Python中集合的迭代順序
>>> foo = set("abc")
>>> bar = set("abc")
>>> zip(foo, bar)
[('a', 'a'), ('c', 'c'), ('b', 'b')]
我的問題是,我很幸運,還是這種行爲有保證?
這不是只是巧合,他們出來是一樣的:實現恰好是確定性的,所以創建相同的集合兩次產生相同的排序。但是Python不能保證。
如果您在兩種不同的方式同一套:
n = set("abc")
print n
m = set("kabc")
m.remove("k")
print m
...你可以得到不同的排序:
set(['a', 'c', 'b'])
set(['a', 'b', 'c'])
+1最簡單的反例。 – katrielalex 2010-08-04 14:22:11
另一個非常好的反例。謝謝! – 2010-08-04 14:25:00
你是完全正確的:這不是巧合。例如,如果你直接創建相同的集合而不刪除任何東西,你總會得到相同的順序:例如:set(「abbacca」)給出set('a','c','b')如設置(「bbabbca」)。這種行爲是非隨機的並且與實現相關聯。看看python的源代碼會很有趣:) (但是在任何情況下,依靠它都是一個壞主意:)) – ThR37 2010-08-04 14:32:28
你很幸運,訂單不能保證。唯一可以保證的是這些套具有相同的元素。
如果您需要某種可預測性,您可以按如下所示對它們進行排序:zip(sorted(foo), sorted(bar))
。
我會說你很幸運。但是,也可能是因爲集合中的元素相同,所以它們按照相同的順序存儲。這種行爲不是你想要依賴的。
編號:
>>> class MyStr(str):
... def __hash__(self):
... return 0
...
>>> a = MyStr("a")
>>> b = MyStr("b")
>>> c = MyStr("c")
>>> foo = { a, b, c }
>>> foo
{'c', 'b', 'a'}
>>> bar = { b, a, c }
>>> foo is bar
False
>>> foo == bar
True
>>> list(zip(foo, bar))
[('c', 'c'), ('b', 'a'), ('a', 'b')]
附:我不知道__hash__
覆蓋是否必要。我只是嘗試了一些我認爲會打破這一點的東西,而且確實如此。
那麼,它證明了點。如果發生散列衝突,順序可能取決於我無法控制的事情。謝謝! – 2010-08-04 14:23:30
是的,你是幸運的。例如見:
import random
r = [random.randint(1,10000) for i in range(20)]
foo = set(r)
r.sort(key=lambda _: random.randint(1,10000))
bar = set(r)
print foo==bar
print zip(foo, bar)
這給我的結果:
True
[(3234, 3234), (9393, 9393), (9361, 1097), (1097, 5994), (5994, 2044), (1614, 1614), (6074, 4377), (4377, 9361), (5202, 5202), (2355, 2355), (1012, 1012), (7349, 7349), (6198, 6198), (8489, 8489), (7929, 7929), (6556, 6074), (6971, 6971), (2044, 6556), (7133, 7133), (383, 383)]
如果'一個是B'我認爲他們將具有相同的迭代順序。再次,這不是一個非常微妙的點= p – katrielalex 2010-08-04 14:27:02