Python集合推导式输出顺序异常问题求助
为什么集合推导式的输出顺序和列表推导式不一致?
问题现象
使用集合推导式时,输出顺序和预期不符:
b=[[2,9,10],[3,7,15],[5,12,12],[15,20,10],[19,24,8]] print({(R, 0, 0) for _, R, _ in b})
实际输出(顺序不固定):
{(12, 0, 0), (9, 0, 0), (7, 0, 0), (20, 0, 0), (24, 0, 0)}
而用列表推导式能严格保留迭代顺序:
b=[[2,9,10],[3,7,15],[5,12,12],[15,20,10],[19,24,8]] print([(R, 0, 0) for _, R, _ in b])
输出:
[(9, 0, 0), (7, 0, 0), (12, 0, 0), (20, 0, 0), (24, 0, 0)]
核心原因
Python中的set(集合)是无序容器,它基于哈希表实现,元素的存储顺序由元素的哈希值决定,和插入顺序没有关联。每次输出集合时,显示的顺序只是哈希表遍历的顺序,完全不保证和推导式的迭代顺序一致,甚至多次运行同一代码,输出顺序都可能变化。
而list(列表)是有序容器,会严格按照元素被插入的顺序保存,所以列表推导式的输出顺序完全匹配迭代b时的顺序。
解决方案
如果需要同时保留元素的唯一性和插入顺序:
- Python 3.7及以上版本:可以利用
dict的插入顺序保留特性,用dict.fromkeys()生成有序的唯一元素集合,再转成列表:b=[[2,9,10],[3,7,15],[5,12,12],[15,20,10],[19,24,8]] print(list(dict.fromkeys((R, 0, 0) for _, R, _ in b))) - Python 3.6及以下版本:使用
collections.OrderedDict来实现同样的效果:from collections import OrderedDict b=[[2,9,10],[3,7,15],[5,12,12],[15,20,10],[19,24,8]] print(list(OrderedDict.fromkeys((R, 0, 0) for _, R, _ in b)))
如果不需要保留顺序,只是需要元素唯一,那集合推导式的表现是完全正常的,接受它的无序特性即可。
内容的提问来源于stack exchange,提问作者Wei-Cheng Lee
相关产品推荐
相关产品推荐

