如果一个列表中的元素存在于另一个列表中,如何在列表中删除列表

时间:2015-02-07 21:25:06

标签: python list python-3.4

我有一个包含多个列表的列表。列表可以包含0到9之间的整数元素,如果两个或多个列表具有公共元素,则删除较小长度的列表

[[0, 3, 7],
 [0, 3, 7, 9],
 [0, 2, 3, 4, 7, 8, 9],
 [2, 4, 8, 9],
 [2, 4, 7, 8, 9],
 [5, 6]]

输出应为:

[[5, 6], [0, 2, 3, 4, 7, 8, 9]]

有什么想法吗?

3 个答案:

答案 0 :(得分:4)

按长度对输入列表进行排序,然后选择最长的列表并将其添加到输出中。从这个最长的列表创建一个集合,您可以根据该列表测试其他列表。与该集合相交的任何后续较短列表都将被丢弃。

如果找到相交的较短列表,请将其添加到输出中,然后更新基本集;毕竟,现在相交的较短列表与输出中的一个或多个列表共享至少一个数字。继续,直到所有列表都经过测试:

def eliminate_shorter(list_of_lists):
    inputlist = sorted(list_of_lists, key=len)
    outputlist = [inputlist.pop()]
    numbers = set(outputlist[0])
    for sublist in reversed(inputlist):
        if not numbers.intersection(sublist):
            numbers.update(sublist)
            outputlist.append(sublist)
    return outputlist

这是O(NlogN)复杂度的算法(因为初始排序)。

演示:

>>> sample = [[0, 3, 7], [0, 3, 7, 9], [0, 2, 3, 4, 7, 8, 9], [2, 4, 8, 9], [2, 4, 7, 8, 9], [5, 6]]
>>> def eliminate_shorter(list_of_lists):
...     inputlist = sorted(list_of_lists, key=len)
...     outputlist = [inputlist.pop()]
...     numbers = set(outputlist[0])
...     for sublist in reversed(inputlist):
...         if not numbers.intersection(sublist):
...             numbers.update(sublist)
...             outputlist.append(sublist)
...     return outputlist
... 
>>> eliminate_shorter(sample)
[[0, 2, 3, 4, 7, 8, 9], [5, 6]]

答案 1 :(得分:1)

l = [[0, 3, 7], [0, 3, 7, 9], [0, 2, 3, 4, 7, 8, 9], [2, 4, 8, 9], [2, 4, 7, 8, 9], [5, 6]]

longest = max(l,key=len)
st = set(longest)
print([longest]+[ele for ele in l if not st.intersection(ele)])
[[0, 2, 3, 4, 7, 8, 9], [5, 6]]

要捕捉重叠的子列表:

longest = max(l, key=len)

seen = set()
seen.update(longest)
out = [longest]
for sub in l:
    if not seen.intersection(sub):
        out.append(sub)
    seen.update(sub)

答案 2 :(得分:0)

选项1:每个列表元素的嵌套迭代,并与其他每个元素进行比较。 (你明白了)。可能不是最有效的方式。

选项2:将每个列表转换(复制)到set s。选择最大的A并减去其他B。如果A - B的结果长度小于A的长度,则丢弃由B表示的列表。如果结果与A的长度相同,则B中的所有项目都是唯一的(不在A中),因此请勿丢弃B。< / p>