我有两个清单:
A = [[2, 5, 13, 14], [4, 5, 10, 12], [2, 9, 10, 11], [2, 5, 12, 13], [4, 5, 6, 12]]
B = [12, 5]
我试图找出A中哪些列表包含B中的元素(顺序无关紧要)并删除其余列表。
在这种情况下答案是:
[[4, 5, 10, 12], [2, 5, 12, 13], [4, 5, 6, 12]]
如果我们更改B并将其设为B = [13]
,答案就是:
[[2, 5, 13, 14], [2, 5, 12, 13]]
答案 0 :(得分:6)
您可以set.issubset
使用列表理解,使用A[:]
将更改原始/列表对象A:
A = [[2, 5, 13, 14], [4, 5, 10, 12], [2, 9, 10, 11], [2, 5, 12, 13], [4, 5, 6, 12]]
B = [12, 5]
st = set(B)
A [:] = [sub for sub in A if st.issubset(sub)]
print(A)
[[4, 5, 10, 12], [2, 5, 12, 13], [4, 5, 6, 12]]
B = [13]
相同A = [[2, 5, 13, 14], [4, 5, 10, 12], [2, 9, 10, 11], [2, 5, 12, 13], [4, 5, 6, 12]]
B = [13]
st = set(B)
A [:] = [sub for sub in A if st.issubset(sub)]
print(A)
[[2, 5, 13, 14], [2, 5, 12, 13]]
s.issubset(t)s< = t测试s中的每个元素是否都在t
对于非常大的A或者如果你有内存限制,你可以使用生成器表达式:
A [:] = (sub for sub in A if st.issubset(sub))
如果订单永远不重要且可以设置我建议你从一开始就使用它们。在集合上执行查找会更有效率。
稍微大一点的时间A:
In [23]: A = [[2, 5, 13, 14], [4, 5, 10, 12], [2, 9, 10, 11], [2, 5, 12, 13], [4, 5, 6, 12],[2, 5, 13, 14], [4, 5, 10, 12], [2, 9, 10, 11], [2, 5, 12, 13], [4, 5, 6, 12],[2, 5, 13, 14], [4, 5, 10, 12], [2, 9, 10, 11], [2, 5, 12, 13], [4, 5, 6, 12]]
In [24]: B = [12, 5]
In [25]: timeit filter(lambda x: all(y in x for y in B), A)
100000 loops, best of 3: 9.45 µs per loop
In [26]: %%timeit
st = set(B)
[sub for sub in A if st.issubset(sub)]
....:
100000 loops, best of 3: 3.88 µs per loop
map(lambda x: not B_set-set(x), A)
In [27]: %%timeit
....: B_set = set(B)
....: map(lambda x: not B_set-set(x), A)
....:
100000 loops, best of 3: 6.95 µs per loop
如果您已将元素存储为A:
中的集合In [33]: %%timeit
st = set(B)
[sub for sub in A if sub >= st]
....:
1000000 loops, best of 3: 1.12 µs per loop
答案 1 :(得分:1)
您可以在此filter
结合使用all
:
print filter(lambda x: all(y in x for y in B), A)
更高效的答案:
B_set = set(B)
print map(lambda x: not B_set-set(x), A)