将列表转换为集合会更改元素顺序 [英] Converting a list to a set changes element order
问题描述
最近我注意到,当我将 list
转换为 set
时,元素的顺序会改变并按字符排序.
考虑这个例子:
x=[1,2,20,6,210]打印 x# [1, 2, 20, 6, 210] # 顺序与初始顺序相同集合(x)# set([1, 2, 20, 210, 6]) # 在set(x) 输出顺序中排序
我的问题是 -
- 为什么会这样?
- 如何在不丢失初始顺序的情况下进行集合操作(尤其是集合差)?
A
set
是无序的数据结构,所以不保留插入顺序.这取决于您的要求.如果您有一个普通列表,并且想要在保留列表顺序的同时删除一些元素,您可以使用列表推导式来实现:
<预><代码>>>>a = [1, 2, 20, 6, 210]>>>b = 设置([6, 20, 1])>>>[x 代表 x 在 a 如果 x 不在 b][2, 210]如果您需要一个同时支持快速成员资格测试和插入顺序保留的数据结构,您可以使用 Python 字典的键,从 Python 3.7 开始保证保留插入顺序:
<预><代码>>>>a = dict.fromkeys([1, 2, 20, 6, 210])>>>b = dict.fromkeys([6, 20, 1])>>>dict.fromkeys(x for x in a if x not in b){2:无,210:无}b
在这里真的不需要订购——您也可以使用set
.请注意,a.keys() - b.keys()
将集合差值作为set
返回,因此它不会保留插入顺序.在旧版本的 Python 中,您可以使用
<预><代码>>>>a = collections.OrderedDict.fromkeys([1, 2, 20, 6, 210])>>>b = collections.OrderedDict.fromkeys([6, 20, 1])>>>collections.OrderedDict.fromkeys(x for x in a if x not in b)OrderedDict([(2, None), (210, None)])collections.OrderedDict
代替:
Recently I noticed that when I am converting a list
to set
the order of elements is changed and is sorted by character.
Consider this example:
x=[1,2,20,6,210]
print x
# [1, 2, 20, 6, 210] # the order is same as initial order
set(x)
# set([1, 2, 20, 210, 6]) # in the set(x) output order is sorted
My questions are -
- Why is this happening?
- How can I do set operations (especially Set Difference) without losing the initial order?
A
set
is an unordered data structure, so it does not preserve the insertion order.This depends on your requirements. If you have an normal list, and want to remove some set of elements while preserving the order of the list, you can do this with a list comprehension:
>>> a = [1, 2, 20, 6, 210] >>> b = set([6, 20, 1]) >>> [x for x in a if x not in b] [2, 210]
If you need a data structure that supports both fast membership tests and preservation of insertion order, you can use the keys of a Python dictionary, which starting from Python 3.7 is guaranteed to preserve the insertion order:
>>> a = dict.fromkeys([1, 2, 20, 6, 210]) >>> b = dict.fromkeys([6, 20, 1]) >>> dict.fromkeys(x for x in a if x not in b) {2: None, 210: None}
b
doesn't really need to be ordered here – you could use aset
as well. Note thata.keys() - b.keys()
returns the set difference as aset
, so it won't preserve the insertion order.In older versions of Python, you can use
collections.OrderedDict
instead:>>> a = collections.OrderedDict.fromkeys([1, 2, 20, 6, 210]) >>> b = collections.OrderedDict.fromkeys([6, 20, 1]) >>> collections.OrderedDict.fromkeys(x for x in a if x not in b) OrderedDict([(2, None), (210, None)])
这篇关于将列表转换为集合会更改元素顺序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!