在两个列表列表中找到非公共元素
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
中的每个子列表和 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))])
输出:
[[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)])
输出:
[[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) 将每个列表元素回溯到它的列表。
我会创建一个函数来完成这项工作,然后使用 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]]
并且我只想提取与其他列表列表没有任何共同元素的子列表,因此在我的情况下结果将是:
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
中的每个子列表和 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))])
输出:
[[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)])
输出:
[[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) 将每个列表元素回溯到它的列表。
我会创建一个函数来完成这项工作,然后使用 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]]