【发布时间】:2018-06-01 01:25:19
【问题描述】:
我在 Python 中有一个列表,如下所示:
[[1,2,3],[2,3],[2,4,3],[4,5],[5]]
我想删除作为另一个内部列表的超集的所有内部列表(一个包含另一个列表的所有元素的列表,但还有其他元素)。对于上面的示例,删除超集应导致以下结果:
[[2,3],[5]]
我怎样才能做到这一点?
【问题讨论】:
标签: python python-3.x list nested-lists
我在 Python 中有一个列表,如下所示:
[[1,2,3],[2,3],[2,4,3],[4,5],[5]]
我想删除作为另一个内部列表的超集的所有内部列表(一个包含另一个列表的所有元素的列表,但还有其他元素)。对于上面的示例,删除超集应导致以下结果:
[[2,3],[5]]
我怎样才能做到这一点?
【问题讨论】:
标签: python python-3.x list nested-lists
如果一个集合更小,它只能是另一个集合的子集,因此通过按大小升序迭代集合,我们可以根据先前找到的最小子集检查每个元素,以了解它是否是最小子集。
def get_minimal_subsets(sets):
sets = sorted(map(set, sets), key=len)
minimal_subsets = []
for s in sets:
if not any(minimal_subset.issubset(s) for minimal_subset in minimal_subsets):
minimal_subsets.append(s)
return minimal_subsets
l = [[1,2,3],[2,3],[2,4,3],[4,5],[5]]
print(get_minimal_subsets(l)) # [{5}, {2, 3}]
【讨论】:
您可以使用列表推导:
d = [[1,2,3],[2,3],[2,4,3],[4,5],[5]]
new_d = [i for i in d if not any(all(c in i for c in b) and len(b) < len(i) for b in d)]
输出:
[[2, 3], [5]]
【讨论】:
这里是:
super=[[1,2,3],[2,3],[2,4,3],[4,5],[5]]
subset=[s for s in super if not any(set(s).issuperset(set(i)) and len(s)>len(i) for i in super)]
输出:
>>> subset
[[2, 3], [5]]
【讨论】:
我最终得出了与@Olivier Melançon 相同的想法。您可以使用升序丢弃子集并在 O(n^2) * O(子集计算) 中运行。
input = [[1,2,3],[2,3],[2,4,3],[4,5],[5]]
sets = [set(x) for x in input]
sets.sort(key=len)
subsets = []
while sets != []:
cur = sets[0]
subsets.append(cur)
sets = [x for x in sets[1:] if not cur <= x]
output = [list(x) for x in subsets]
print(output)
【讨论】:
sets.sort(key=len, reverse=True) 然后cur = sets.pop(); subsets.append(cur)。这允许从列表理解中删除切片:sets = [x for x in sets if not cur <= x].
clean_list = filter(lambda f: not any(set(f) < set(g) for g in main_list), main_list)