如何使用“设置”保持有序列表?

时间:2018-08-13 23:01:09

标签: python list set

我希望能够在比较时保持列表的顺序。请注意,当我将list1与list2比较时,它将返回我然后是8,然后是7(反向)。如何维护订单?

https://169.254.128.2:8443

7 个答案:

答案 0 :(得分:5)

OrderedDict可以很好地替代保留订单的集合,因为键视图类似于集合:

>>> from collections import OrderedDict
>>> list1 = ['1','2','3','4','7','8'] 
>>> list2 = ['1','2','3','4','5','6']
>>> OrderedDict.fromkeys(list1).keys() - OrderedDict.fromkeys(list2).keys()
{'7', '8'}
>>> OrderedDict.fromkeys(list2).keys() - OrderedDict.fromkeys(list1).keys()
{'5', '6'}

严格来说,这可能仍在使用CPython的实现细节。但是列表理解不是,它们仍然是O(n):

>>> od1 = OrderedDict.fromkeys(list1)
>>> od2 = OrderedDict.fromkeys(list2)
>>> [k for k in od1 if k not in od2]
['7', '8']
>>> [k for k in od2 if k not in od1]
['5', '6']

答案 1 :(得分:3)

您可以使用列表理解:

list1 = ['1','2','3','4','7','8'] 
list2 = ['1','2','3','4','5','6']

set1 = set(list1)  # convert to set for faster membership testing
result = [x for x in list2 if x not in set1]
# result: ['5', '6']

但是,这将包括重复的元素:

>>> list1 = [1]
>>> list2 = [1, 2, 2]
>>> set1 = set(list1)
>>> [x for x in list2 if x not in set1]
[2, 2]

如果不需要重复,只需将列表理解转换为循环并跟踪您已经遇到的所有元素:

list1 = [1] 
list2 = [1, 2, 2]

set1 = set(list1)
result = []

for x in list2:
    if x in set1:
        continue

    result.append(x)
    set1.add(x)

# result: [2]

答案 2 :(得分:1)

虽然它不使用-运算符作为集合,但它确实保留了原始列表的顺序。

list1 = ['1','2','3','4','7','8'] 
list2 = ['1','2','3','4','5','6']
set_list2 = set(list2)
result = []
for item in list1:
    if not item in set_list2:
        result.append(item)
        set_list2.add(item) # to avoid duplicates in result
print(result)
# ['7', '8']

答案 3 :(得分:0)

您可以改用列表理解来找出差异。这是您的操作方式: [x for x in list1 if x not in list2]将产生['7', '8']

您可以进行[x for x in list2 if x not in list1]的{​​{1}}

如果原始列表包含重复项,则可以使用['5', '6']

答案 4 :(得分:0)

根据定义,“集合”是无序的。如果您想对元素进行排序,请尝试使用列表操作。您可以使用numpy中的setdiff1d,例如:

import numpy as np
list1 = ['1','2','3','4','7','8'] 
list2 = ['1','2','3','4','5','6']
new_list_one = np.setdiff1d(list2, list1)
new_list_two = np.setdiff1d(list1, list2)

print(new_list_one) ['5' '6']
print(new_list_two) ['7' '8']

答案 5 :(得分:0)

可能是最幼稚的方法

def ordered_diff(a, b):
    seen = set(b)
    result = []
    for ele in a:
        if ele not in seen:
            result.append(ele)
            seen.add(ele)

    return result     


list1 = ['1','2','3','4','7','8','7','8'] 
list2 = ['1','2','3','4','5','6','5','6']

print ordered_diff(list1, list2)
print ordered_diff(list2, list1)

结果:

['7', '8']
['5', '6']

答案 6 :(得分:0)

在这种情况下,只需使用列表理解:

[x for x, y in zip(b, a) if x != y]
# ['5', '6']

[x for x, y in zip(a, b) if x != y]
# ['7', '8']

通常,考虑使用itertools.zip_longest(相对于zip),尤其是列表长度不同的情况。