从列表中删除符合特定条件的子列表

3

我使用 itertools.product() 创建了不带镜像的所有三元排列:

import itertools

list_1 = [list(i) for i in itertools.product(tuple(range(4)), repeat=3) if tuple(reversed(i)) >= tuple(i)]

输出:

[[0, 0, 0], [0, 0, 1], [0, 0, 2], [0, 0, 3], [0, 1, 0], [0, 1, 1], [0, 1, 2], [0, 1, 3], [0, 2, 0], [0, 2, 1], [0, 2, 2], [0, 2, 3], [0, 3, 0], [0, 3, 1], [0, 3, 2], [0, 3, 3], [1, 0, 1], [1, 0, 2], [1, 0, 3], [1, 1, 1], [1, 1, 2], [1, 1, 3], [1, 2, 1], [1, 2, 2], [1, 2, 3], [1, 3, 1], [1, 3, 2], [1, 3, 3], [2, 0, 2], [2, 0, 3], [2, 1, 2], [2, 1, 3], [2, 2, 2], [2, 2, 3], [2, 3, 2], [2, 3, 3], [3, 0, 3], [3, 1, 3], [3, 2, 3], [3, 3, 3]]

我该如何从列表list_1中删除这些子列表,这些子列表具有相应值的相同数量,然后只保留其中一个?
例如,在子列表[1,1,2],[1,2,1]中,所有子列表中给定值的数量都相同,即在每个子列表中都有两个1和一个2,因此我认为这些子列表是相同的,所以我只想保留第一个,即[1,1,2]。怎么做呢?
我考虑计算每个子列表中相应值的数量,并创建一个具有出现特征的列表,然后在循环中检查列表list_1中的每个元素或具有给定特征的元素是否已经出现。但我觉得这太复杂了。

使用Counter结构;如果两个项具有相同的count字典,则删除重复项。这足够提示了吗? - Prune
Rory Daulton 给出了最简单的解决方案 :) - Tomasz Przemski
3个回答

5

不要使用itertools模块中的product,而是使用combinations_with_replacement。这可以在一行代码中完成你想要做的事情,而且之后无需任何处理即可:

list1 = [list(i) for i in combinations_with_replacement(range(4),3)]

执行完print(list1)语句后,其结果为:
[[0, 0, 0], [0, 0, 1], [0, 0, 2], [0, 0, 3], [0, 1, 1], [0, 1, 2], [0, 1, 3], [0, 2, 2], [0, 2, 3], [0, 3, 3], [1, 1, 1], [1, 1, 2], [1, 1, 3], [1, 2, 2], [1, 2, 3], [1, 3, 3], [2, 2, 2], [2, 2, 3], [2, 3, 3], [3, 3, 3]]

请注意,将range对象转换为元组是不必要的。

1
你可以对每个子列表进行排序,然后按以下方式提取唯一的子列表。
list_2 = map(sorted, list_1)
list_u = []
[list_u.append(x) for x in list_2 if x not in list_u]

输出:

list_u = [[0, 0, 0], [0, 0, 1], [0, 0, 2], [0, 0, 3], [0, 1, 1], [0, 1, 2], [0, 1, 3], [0, 2, 2], [0, 2, 3], [0, 3, 3], [1, 1, 1], [1, 1, 2], [1, 1, 3], [1, 2, 2], [1, 2, 3], [1, 3, 3], [2, 2, 2], [2, 2, 3], [2, 3, 3], [3, 3, 3]]

现在,有比对每个子列表进行排序更有效的选项,但我会让你自行决定。

1
这可能会起到作用:
import itertools

def uniqifyList(list):
    indexToReturn = []
    sortedUniqueItems = []

    for idx, value in enumerate(list):
        # check if exists in unique_list or not
        value.sort()
        if value not in sortedUniqueItems:
            sortedUniqueItems.append(value)
            indexToReturn.append(idx)

    return [list[i] for i in indexToReturn]

list1 = [list(i) for i in itertools.product(tuple(range(4)), repeat=3) if tuple(reversed(i)) >= tuple(i)]
print(list1)

list2 = uniqifyList(list1)
print(list2)

输出:

[[0, 0, 0], [0, 0, 1], [0, 0, 2], [0, 0, 3], [0, 1, 1], [0, 1, 2], [0, 1, 3], [0, 2, 2], [0, 2, 3], [0, 3, 3], [1, 1, 1], [1, 1, 2], [1, 1, 3], [1, 2, 2], [1, 2, 3], [1, 3, 3], [2, 2, 2], [2, 2, 3], [2, 3, 3], [3, 3, 3]]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接