Python 中集合的迭代顺序

发布于 2024-09-12 11:03:07 字数 267 浏览 2 评论 0原文

如果我有两个相同的集合,意味着 a == b 给我 True,它们会有相同的迭代顺序吗?我尝试过,它有效:

>>> foo = set("abc")
>>> bar = set("abc")
>>> zip(foo, bar)
[('a', 'a'), ('c', 'c'), ('b', 'b')]

我的问题是,我是幸运的,还是这种行为有保证?

If I have two identical sets, meaning a == b gives me True, will they have the same iteration order? I tried it, and it works:

>>> foo = set("abc")
>>> bar = set("abc")
>>> zip(foo, bar)
[('a', 'a'), ('c', 'c'), ('b', 'b')]

My question is, was I lucky, or is this behavior guaranteed?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

北音执念 2024-09-19 11:03:07

它们的结果相同并不是巧合:实现恰好是确定性的,因此两次创建相同的集合会产生相同的顺序。但 Python 并不保证这一点。

如果您以两种不同的方式创建相同的集合:

n = set("abc")
print n

m = set("kabc")
m.remove("k")
print m

...您可以获得不同的排序:

set(['a', 'c', 'b'])
set(['a', 'b', 'c'])

It wasn't just a coincidence that they came out the same: the implementation happens to be deterministic, so creating the same set twice produces the same ordering. But Python does not guarantee that.

If you create the same set in two different ways:

n = set("abc")
print n

m = set("kabc")
m.remove("k")
print m

...you can get different ordering:

set(['a', 'c', 'b'])
set(['a', 'b', 'c'])
蓝色星空 2024-09-19 11:03:07

你很幸运,订单无法保证。唯一可以保证的是这些集合将具有相同的元素。

如果您需要某种可预测性,可以像这样对它们进行排序:zip(sorted(foo),sorted(bar))

You were lucky, the order is not guaranteed. The only thing that's guaranteed is that the sets will have the same elements.

If you need some sort of predictability, you could sort them like this: zip(sorted(foo), sorted(bar)).

野心澎湃 2024-09-19 11:03:07

否:

>>> 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')]

PS 我不知道 __hash__ 覆盖是否必要。我只是尝试了一些我认为会打破这个的东西,而且它确实做到了。

No.:

>>> 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')]

P.S. I have no idea if the __hash__ override is necessary. I just tried something I thought would break this, and it did.

伪心 2024-09-19 11:03:07

是的,你很幸运。参见示例:

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)]

Yes, you were lucky. See for example:

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)

Which gave me the result:

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)]
送舟行 2024-09-19 11:03:07

我想说你很幸运。不过,也可能是因为集合中的元素相同,所以它们以相同的顺序存储。您不希望依赖这种行为。

I'd say you got lucky. Though, it might also be that, since the elements in the set were the same, they were stored in the same order. This behavior is not something you'd want to rely on.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文