簡體   English   中英

如何有效計算三個列表中元素之間的差異?

[英]How to calculate the difference between the elements in three lists efficiently?

我有3個非常大的字符串列表,出於可視化目的考慮:

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

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

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

我如何計算此列表之間的差異,以便僅獲取其他列表中未重復的元素。 例如:

A = ['nine']

B = ['three','six']

C = ['eleven']

方法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'])

帶套:

  • 將所有列表轉換為集合
  • 采取差異
  • 轉換回列表

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']

可以通過按原始索引進行排序來解決此問題,但是時間復雜度將急劇增加,因此使用集合的好處幾乎完全喪失了。


使用list-comps(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) )。

您可以遍歷所有列表元素,並添加當前元素以設置當前元素(如果不存在),以及將其從列表中刪除。 這樣,您將使用高達O(n)的空間復雜度和O(n)的時間復雜度,但元素將保持有序。

您也可以使用功能定義來檢查三個列表之間的差異。 這是此類函數的示例:

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']

使用函數是有利的,因為代碼是可重用的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM