小编典典

将列表转换为集合会更改元素顺序

all

最近我注意到,当我将 a 转换listset元素的顺序时,它会改变并按字符排序。

考虑这个例子:

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

我的问题是——

  1. 为什么会这样?
  2. 如何在不丢失初始顺序的情况下进行设置操作(尤其是设置差异)?

阅读 69

收藏
2022-07-18

共1个答案

小编典典

  1. Aset是无序的数据结构,因此它不保留插入顺序。

  2. 这取决于您的要求。如果您有一个普通列表,并且想要删除某些元素集同时保留列表的顺序,您可以使用列表推导来执行此操作:

    >>> a = [1, 2, 20, 6, 210]
    

    b = set([6, 20, 1])
    [x for x in a if x not in 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: None, 210: None}

b真的不需要在这里订购——你也可以使用 a set。请注意,a.keys() - b.keys()将集合差异返回为 a
set,因此它不会保留插入顺序。

在旧版本的 Python
中,您可以collections.OrderedDict改用:

    >>> 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)])
2022-07-18