如何从列表列表中删除所有子集

时间:2018-10-02 06:49:33

标签: python list

什么是清除list中的子列表的有效方法。因为我只想获得列表中最大的一组。就像。

b = [[1,2,3], [1,2], [3,5], [2,3,4], [2,3,4], [3,4,5], [1,2,4,6,7]]  

,我希望输出如下。

result = [[1,2,3], [2,3,4], [3,4,5], [1,2,4,6,7]]

原因[1,2]是[1,2,3]和[1,2,4,6,7]的子集,[3,5]是[3,4,5]的子集,并且[2,3,4]出现2次,最终结果只想计算1次。我想根据逻辑子集来过滤数据。

我只想出2个循环的解决方案来解决这个问题,但是如果还有其他有效的方法来解决这个问题。

我尝试过这样的操作:(在我进一步优化了这一效果之后,添加中断并添加1个部分而不计算2次)

b = [[1,2,3], [1,2], [3,5], [2,3,4], [2,3,4], [3,4,5], [1,2,4,6,7]]
i = 0
record = []
subset_status = False
for index, re in enumerate(b):
    while i <= (len(b)-1):
        if i != index:
            if i not in record:
                if set(re).issubset(b[i]):
                    subset_status = True
                    break
        i += 1
    i = 0
    if subset_status:
        record.append(index)
        subset_status = False
print(record)
>>[1, 2, 3]

所以我得到了[1,2,3]中的索引是脏数据。 谢谢。

5 个答案:

答案 0 :(得分:1)

有条件的list comprehension是一种Python式,灵活且高效的方法。与重复删除元素相比,从头开始组装清理列表通常更快,更容易出错:

b = [[1, 2, 3], [1, 2], [3, 5], [2, 3, 4],[3, 4, 5]]

cleaned = [x for x in b if clean(x)]  # where clean is your condition
# e.g.
cleaned = [x for x in b if len(x) == 3] 
# [[1, 2, 3], [2, 3, 4], [3, 4, 5]]

如果您需要对原始list对象进行突变,请使用切片分配:

b[:] = [x for x in b if clean(x)]

答案 1 :(得分:1)

uint32_t ProtoType::test() { return 5; } uint32_t RealProtoType::real() { uint32_t holder = ProtoType::test(); } 您的条件列表:

filter

答案 2 :(得分:1)

一种方法是按照从长到短的顺序处理b中的列表。

b = [[1,2,3], [1,2], [3,5], [2,3,4], [2,3,4], [3,4,5], [1,2,4,6,7]]
result = []
for u in sorted(map(set, b), key=len, reverse=True):
    if not any(u <= v for v in result):
        result.append(u)
print(result)

输出

[{1, 2, 4, 6, 7}, {1, 2, 3}, {2, 3, 4}, {3, 4, 5}]

如果您需要将内部列表保留为实际列表,并且还需要保留顺序,那么我们可以通过对数据进行额外的传递来做到这一点。但是,我将使用一个集合来使测试更加有效,而不是使用result的列表。这意味着将子列表变成冻结集:普通集将不起作用,因为只能将可哈希对象放入集合中。

b = [[1,2,3], [1,2], [3,5], [2,3,4], [2,3,4], [3,4,5], [1,2,4,6,7]]
temp = set()
for u in sorted(map(frozenset, b), key=len, reverse=True):
    if not any(u <= v for v in temp): 
        temp.add(u)
newb = []
for u in b: 
    if set(u) in temp and u not in newb:
        newb.append(u)
print(newb)

输出

[[1, 2, 3], [2, 3, 4], [3, 4, 5], [1, 2, 4, 6, 7]]

答案 3 :(得分:0)

这不是很好,但是可以:

result = []
for i in b:
    for j in result:
        if all(c in j for c in i):
            break
    else:
        new_list.append(i)

for i in result:
    for j in result:
        if all(c in j for c in i) and result.index(i) != result.index(j):
            del(result[result.index(i)])
            break

答案 4 :(得分:0)

您可以使用 tuples product 来检测item是否为子列表,然后构造一个新列表(不包括那些子列表)

列表理解

from itertools import product

b = [[1,2,3], [1,2], [3,5], [2,3,4], [3,4,5], [1,2,4,6,7]]

dirty = [i for i in b for j in b if i != j if tuple(i) in product(j, repeat = len(i))]
clean = [i for i in b if i not in dirty]

扩展说明:

dirty = []
for i in b:
    for j in b:
        if i != j:
            if tuple(i) in product(j, repeat = len(i)):
                dirty.append(i)

clean = [i for i in b if i not in dirty]
[[1, 2, 3], [2, 3, 4], [3, 4, 5], [1, 2, 4, 6, 7]]