最近我注意到,当我转换一个列表来设置元素的顺序是改变的,并按字符排序。

想想这个例子:

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

我的问题是

为什么会这样? 如何才能在不丢失初始顺序的情况下进行设置操作(特别是设置差异)?


当前回答

如果愿意,可以删除重复的值并保持插入的列表顺序

lst = [1,2,1,3]
new_lst = []

for num in lst :
    if num not in new_lst :
        new_lst.append(num)

# new_lst = [1,2,3]

如果你想要的是“order”,不要使用“sets”来删除重复,

使用集合进行搜索。 X在列表中 花费O(n)时间 在哪里 集合中的X 在大多数情况下需要O(1)时间*

其他回答

基于Sven的回答,我发现使用集合。OrderedDict像这样帮助我完成你想要的,并允许我添加更多的项目到dict:

import collections

x=[1,2,20,6,210]
z=collections.OrderedDict.fromkeys(x)
z
OrderedDict([(1, None), (2, None), (20, None), (6, None), (210, None)])

如果你想添加项目,但仍然把它当作一个集合,你可以这样做:

z['nextitem']=None

你可以在dict上执行类似z.keys()的操作并获得集合:

list(z.keys())
[1, 2, 20, 6, 210]

在Python 3.6中,set()现在应该保持顺序,但Python 2和3有另一个解决方案:

>>> x = [1, 2, 20, 6, 210]
>>> sorted(set(x), key=x.index)
[1, 2, 20, 6, 210]

如果你有少量的元素在你的两个初始列表上,你想做集差操作,而不是使用集合。OrderedDict使实现复杂化,使其可读性较差,您可以使用:

# initial lists on which you want to do set difference
>>> nums = [1,2,2,3,3,4,4,5]
>>> evens = [2,4,4,6]
>>> evens_set = set(evens)
>>> result = []
>>> for n in nums:
...   if not n in evens_set and not n in result:
...     result.append(n)
... 
>>> result
[1, 3, 5]

它的时间复杂度不是很好,但它很简洁,易于阅读。

另一种更简单的方法是创建一个空列表,例如“unique_list”,用于从原始列表中添加唯一的元素,例如:

unique_list=[]

for i in original_list:
    if i not in unique_list:
        unique_list.append(i)
    else:
        pass

这将为您提供所有独特的元素,并保持顺序。

删除重复和保存顺序以下功能

def unique(sequence):
    seen = set()
    return [x for x in sequence if not (x in seen or seen.add(x))]

如何从列表中删除重复,同时保留Python中的顺序