我有一个列表列表,但是有些列表是其他列表的“子列表”。我要做的是从较大的列表中删除子列表,这样我们就只有最大的唯一子列表。
例如:
>>> some_list = [[1], [1, 2], [1, 2, 3], [1, 4]]
>>> ideal_list = [[1, 2, 3], [1, 4]]
我现在编写的代码是:
new_list = []
for i in range(some_list)):
for j in range(i + 1, len(some_list)):
count = 0
for k in some_list[i]:
if k in some_list[j]:
count += 1
if count == len(some_list[i]):
new_list.append(some_list[j])
我想到的基本算法是,我们将检查列表的元素是否在以下子列表中,如果是,则使用其他较大的子列表。它没有提供理想的输出(实际上是[[1, 2], [1, 2, 3], [1, 4], [1, 2, 3]]
),我想知道我能做些什么来实现我想要的。
我不想使用集合,因为重复的元素很重要。
答案 0 :(得分:1)
与set
相同,但改用Counter
。子列表检查部分应该比蛮力更有效率
from collections import Counter
new_list = []
counters = []
for arr in sorted(some_list, key=len, reverse=True):
arr_counter = Counter(arr)
if any((c & arr_counter) == arr_counter for c in counters):
continue # it is a sublist of something else
new_list.append(arr)
counters.append(arr_counter)
答案 1 :(得分:0)
输入:
l = [[1], [1, 2], [1, 2, 3], [1, 4]]
这里的一种方式:
l1 = l.copy()
for i in l:
for j in l:
if set(i).issubset(set(j)) and i!=j:
l1.remove(i)
break
此打印:
print(l1)
[[1, 2, 3], [1, 4]]
编辑:(也要注意重复)
l1 = [list(tupl) for tupl in {tuple(item) for item in l }]
l2 = l1.copy()
for i in l1:
for j in l1:
if set(i).issubset(set(j)) and i!=j:
l2.remove(i)
break
答案 2 :(得分:0)
从@ mkrieger1的评论中得到一些启发,一种可能的解决方案是:
def merge_sublists(some_list):
new_list = []
for i in range(len(some_list)):
true_or_false = []
for j in range(len(some_list)):
if some_list[j] == some_list[i]:
continue
true_or_false.append(all([x in some_list[j] for x in some_list[i]]))
if not any(true_or_false):
new_list.append(some_list[i])
return new_list
如评论中所述,强力解决方案将是遍历每个元素,并检查它是否为任何其他子列表的子列表。如果不是 ,则将其附加到新列表中。
测试用例:
>>> merge_sublists([[1], [1, 2], [1, 2, 3], [1, 4]])
[[1, 2, 3], [1, 4]]
>>> merge_sublists([[1, 2, 3], [4, 5], [3, 4]])
[[1, 2, 3], [4, 5], [3, 4]]