簡體   English   中英

從多個列表中刪除可以出現在其他列表中的元素

[英]Removing elements from multiple lists that can appear in other lists

我有 3 個列表:

l1 = ['a', 'b', 'c', 'd', 'e', 'q', 'w']
l2 = ['a', 'g', 'h', 'd', 'k']
l3 = ['z', 'b', 'v', 'n', 'k', 's']

我想創建某種過濾器,它只會在這 3 個列表中留下唯一的元素。 所以l1應該只有不在l2l3中的元素,我想對每個列表做同樣的事情。 所需的 output:

l1 = ['c', 'e', 'q', 'w']
l2 = ['g', 'h']
l3 = ['z', 'v', 'n', 's']

我有 6 個列表,每個列表都有 5000 多個元素,並且列表的長度不一樣。 我正在考慮做一些交叉點,但我必須做很多 for 循環。

有什么Pythonic的方法嗎?

我會使用一個Counter

>>> l1 = ['a', 'b', 'c', 'd', 'e', 'q', 'w']
>>> l2 = ['a', 'g', 'h', 'd', 'k']
>>> l3 = ['z', 'b', 'v', 'n', 'k', 's']
>>> import collections
>>> counter = collections.Counter(l1 + l2 + l3)
>>> [i for i in l1 if counter[i] == 1]
['c', 'e', 'q', 'w']
>>> [i for i in l2 if counter[i] == 1]
['g', 'h']
>>> [i for i in l3 if counter[i] == 1]
['z', 'v', 'n', 's']

請注意,如果你有一堆列表你想做完全相同的事情,你可能只想要一個列表列表而不是一堆單獨的變量:

>>> all_lists = [l1, l2, l3]
>>> counter = collections.Counter(i for a in all_lists for i in a)
>>> [[i for i in a if counter[i] == 1] for a in all_lists]
[['c', 'e', 'q', 'w'], ['g', 'h'], ['z', 'v', 'n', 's']]

這里set方法。 它是基於組合學的,因此它僅取決於列表的數量 n。 由於“n choose n-1”= n,循環將始終迭代 n 次。

缺點:最終列表將(隨機)排序

優點:“構造”精確解

import itertools as it

l1 = ['a', 'b', 'c', 'd', 'e', 'q', 'w']
l2 = ['a', 'g', 'h', 'd', 'k']
l3 = ['z', 'b', 'v', 'n', 'k', 's']

ls = (l1, l2, l3)
# as dictionary with key integer numbers and values sets
d = {i: set(ls[i]) for i in range(len(ls))}

results = []
s = set(d.keys())
for p in it.combinations(d.keys(), len(ls)-1):
    # index not comparing in p
    i = tuple(s.difference(p))[0]
    # new set
    s_new = d[i].difference(set.union(*map(d.__getitem__, p)))
    results.append(list(s_new))

print(results)

Output

[['v', 's', 'n', 'z'], ['h', 'g'], ['e', 'c', 'w', 'q']]

暫無
暫無

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

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