如何有效计算三个列表中元素之间的差异?

时间:2018-08-08 22:20:11

标签: python python-3.x list data-structures

我有3个非常大的字符串列表,出于可视化目的考虑:

t

我如何计算此列表之间的差异,以便仅获取在其他列表中未重复的元素。例如:

A = ['one','four', 'nine']

B = ['three','four','six','five']

C = ['four','five','one','eleven']

4 个答案:

答案 0 :(得分:2)

方法1

您只需更改第一行即可任意添加更多列表,例如my_lists = (A, B, C, D, E)

my_lists = (A, B, C)
my_sets = {n: set(my_list) for n, my_list in enumerate(my_lists)}
my_unique_lists = tuple(
    list(my_sets[n].difference(*(my_sets[i] for i in range(len(my_sets)) if i != n))) 
    for n in range(len(my_sets)))

>>> my_unique_lists
(['nine'], ['six', 'three'], ['eleven'])

my_sets使用字典理解为每个列表创建集合。字典的关键是my_lists中的列表顺序排名。

然后将每个集合与字典中的所有其他集合进行区别(禁止),然后转换回列表。

my_unique_lists的顺序与my_lists中的顺序相对应。

方法2

您可以使用Counter获取所有唯一项(即仅出现在一个列表中而不是其他列表中的项),然后使用列表推导来遍历每个列表并选择唯一的项。

from collections import Counter

c = Counter([item for my_list in my_lists for item in set(my_list)])
unique_items = tuple(item for item, count in c.items() if count == 1)

>>> tuple([item for item in my_list if item in unique_items] for my_list in my_lists)
(['nine'], ['three', 'six'], ['eleven'])

答案 1 :(得分:1)

有套:

  • 将所有列表转换为集合
  • 把握差异
  • 转换回列表

A, B, C = map(set, (A, B, C))
a = A - B - C
b = B - A - C
c = C - A - B
A, B, C = map(list, (a, b, c))

(可能的)问题是最终列表不再排序,例如

>>> A
['nine']
>>> B
['six', 'three']
>>> C
['eleven']

可以通过按原始索引进行排序来解决此问题,但是时间复杂度将急剧增加,因此使用集合的好处几乎完全丧失了。


使用列表压缩(for循环):

  • 将列表转换为集
  • 使用list-comps从原始列表中过滤掉不在其他集合中的元素

sA, sB, sC = map(set, (A, B, C))
A = [e for e in A if e not in sB and e not in sC]
B = [e for e in B if e not in sA and e not in sC]
C = [e for e in C if e not in sA and e not in sB]

然后产生一个保持列表原始顺序的结果:

>>> A
['nine']
>>> B
['three', 'six']
>>> C
['eleven']

摘要:

总而言之,如果您不关心结果的顺序,请将列表转换为集合,然后采用它们的差异(不要费心将其转换回列表)。但是,如果您确实关心顺序,则仍将列表转换为集合(哈希表),因为过滤它们时查找仍会更快(列表的最佳情况是O(1)O(n))。 / p>

答案 2 :(得分:1)

您可以迭代遍历所有列表元素,并添加当前元素以设置当前元素(如果不存在),以及将其从列表中删除。这样,您将使用高达O(n)的空间复杂度和O(n)的时间复杂度,但元素将保持有序。

答案 3 :(得分:1)

您还可以使用功能定义专门检查三个列表之间的差异。这是此类功能的示例:

def three_list_difference(l1, l2, l3):
    lst = []
    for i in l1:
        if not(i in l2 or i in l3):
            lst.append(i)
    return lst

函数three_list_difference包含三个列表,并检查第一个列表l1中的元素是否也在l2l3中。可以通过在正确的配置中简单调用该函数来确定不同:

three_list_difference(A, B, C)
three_list_difference(B, A, C)
three_list_difference(C, B, A)

具有输出:

['nine']
['three', 'six']
['eleven']

使用功能是有利的,因为代码是可重用的。