簡體   English   中英

在兩個列表列表中找到非公共元素

[英]find non common elements in two list of lists

我有兩個列表列表,例如:

A = [[1,2,3],[1,5],[7],[8,9,10],[11]]
B = [[11,2,2],[9,11],[6,14], [17]]

我只想提取與其他列表列表沒有任何共同元素的子列表,所以在我的情況下,結果將是:

res = [[1,5],[7],[6,14],[17]

如果可能的話,我還想將公式擴展到 2 個以上的列表列表。 我找不到一種簡單的方法來做到這一點,所以如果我添加另一個列表列表,如示例所示:

A = [[1,2,3],[1,5],[7],[8,9,10],[11]]
B = [[11,2,2],[9,11],[6,14], [17]]
C = [[17,18,19], [14,10],[100,101]]

結果是:

res = [[1,5],[7],[100,101]]

我們可以檢查B中的子列表並集和A中的每個子列表之間的交集(對B中的每個子列表和A中的子列表的並集做同樣的工作),然后連接結果列表:

res = ([s_lst for s_lst in A if not set(s_lst).intersection(set().union(*B))] 
       + [s_lst for s_lst in B if not set(s_lst).intersection(set().union(*A))])

Output:

[[1, 5], [7], [6, 14], [17]]

對於更一般的情況,一種選擇是創建一個字典並在循環中使用與上面相同的想法:

lsts = [A,B,C]
d_unions = dict(enumerate([set().union(*X) for X in lsts]))
d_lsts = dict(enumerate(lsts))

out = []
for i, li in d_lsts.items():
    current_union = set.union(*[v for k,v in d_unions.items() if k!=i])
    out.extend([s_lst for s_lst in li if not set(s_lst).intersection(current_union)])

Output:

[[1, 5], [7], [100, 101]]

我會創建一個 function 來完成這項工作,然后使用 reduce 將結果應用於多個列表。

from functools import reduce
from typing import List


def _find_not_common(list_a: List[List], list_b: List[List]):
    """"Returns sub lists in A that have no elements in present B"""
    flat_b = set([i for sub_list in list_b for i in sub_list])
    return [
        sub_list
        for sub_list
        in list_a
        if all([j not in flat_b for j in sub_list if j])
    ]


def find_not_common(list_a: List[List], list_b: List[List]):
    """"Returns sub lists in A that have no elements present in B + the viceversa"""
    return _find_not_common(list_a, list_b) + _find_not_common(list_b, list_a)


A = [[1, 2, 3], [1, 5], [7], [8, 9, 10], [11]]
B = [[11, 2, 2], [9, 11], [6, 14], [17]]
C = [[17, 18, 19], [14, 10], [100, 101]]

# Use reduce to pass a list of any length.
result = reduce(find_not_common, [A, B, C])  # Output: [[1, 5], [7], [100, 101]]

你可以試試這個:

A = [[1,2,3],[1,5],[7],[8,9,10],[11]]
B = [[11,2,2],[9,11],[6,14], [17]]
C = [[17,18,19], [14,10],[100,101]]
lst=[A,B,C]
def non_common(ls):
    temp=[]
    for l in ls:
        without_l=[j for j in ls if j!=l] #get the list without the list-element we are iterating
        no_cmn=[i for i in l if (all(set(i).isdisjoint(set(j)) for k in without_l for j in k))]
        temp.extend(no_cmn)
    return temp
result=non_common(lst)
print(result)

您還可以通過在循環中使用 enumerate(ls) 將每個列表元素回溯到它的列表。

暫無
暫無

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

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