在2D阵列中删除无序重复项的最省时方法是什么?

时间:2020-01-04 09:56:22

标签: python python-3.x list set itertools

我已经使用itertools生成了一个组合列表,并且得到的结果看起来像这样:

nums = [-5,5,4,-3,0,0,4,-2]
x = [x for x in set(itertools.combinations(nums, 4)) if sum(x)==target]
>>> x = [(-5, 5, 0, 4), (-5, 5, 4, 0), (5, 4, -3, -2), (5, -3, 4, -2)]

删除无序重复项(例如x[0]x[1]是重复项的最复杂的时间复杂度有效的方法是什么。有内置的东西可以处理吗?

我的一般方法是在一个元素中创建所有元素的计数器,然后与下一个元素进行比较。这是最好的方法吗?

谢谢您的指导。

3 个答案:

答案 0 :(得分:10)

因为要查找无序重复项,所以最好的方法是通过类型转换。 Typecast 将它们作为 set 。由于set仅包含 不可变 元素。因此,我制作了一组 tuples

注意: 消除 重复 的最好方法是对给定元素进行 set

>>> set(map(tuple,map(sorted,x)))
{(-3, -2, 4, 5), (-5, 0, 4, 5)}

答案 1 :(得分:4)

最好的方法是首先不生成重复项。

该想法是首先创建出现多次的所有可能值组合,其中每个出现0、1,...次。然后,我们将所有可能的独特元素组合完成。

from itertools import combinations, product, chain
from collections import Counter

nums = [-5,5,4,-3,0,0,4,-2]

def combinations_without_duplicates(nums, k):
    counts = Counter(nums)
    multiples = {val: count for val, count in counts.items() if count >= 2 }
    uniques = set(counts) - set(multiples)              
    possible_multiples = [[[val]*i for i in range(count+1)] for val, count in multiples.items()]
    multiples_part = (list(chain(*x)) for x in product(*possible_multiples))
    # omit the ones that are too long
    multiples_part = (lst for lst in multiples_part if len(lst) <= k)
    # Would be at this point:
    # [[], [0], [0, 0], [4], [4, 0], [4, 0, 0], [4, 4], [4, 4, 0], [4, 4, 0, 0]]
    for m_part in multiples_part:
        missing = k - len(m_part)
        for c in combinations(uniques, missing):
            yield m_part + list(c)


list(combinations_without_duplicates(nums, 4))

输出:

[[-3, -5, 5, -2],
 [0, -3, -5, 5],
 [0, -3, -5, -2],
 [0, -3, 5, -2],
 [0, -5, 5, -2],
 [0, 0, -3, -5],
 [0, 0, -3, 5],
 [0, 0, -3, -2],
 [0, 0, -5, 5],
 [0, 0, -5, -2],
 [0, 0, 5, -2],
 [4, -3, -5, 5],
 [4, -3, -5, -2],
 [4, -3, 5, -2],
 [4, -5, 5, -2],
 [4, 0, -3, -5],
 [4, 0, -3, 5],
 [4, 0, -3, -2],
 [4, 0, -5, 5],
 [4, 0, -5, -2],
 [4, 0, 5, -2],
 [4, 0, 0, -3],
 [4, 0, 0, -5],
 [4, 0, 0, 5],
 [4, 0, 0, -2],
 [4, 4, -3, -5],
 [4, 4, -3, 5],
 [4, 4, -3, -2],
 [4, 4, -5, 5],
 [4, 4, -5, -2],
 [4, 4, 5, -2],
 [4, 4, 0, -3],
 [4, 4, 0, -5],
 [4, 4, 0, 5],
 [4, 4, 0, -2],
 [4, 4, 0, 0]]

答案 2 :(得分:0)

您可以使用itertools.combinations_with_replacement()

从输入 iterable

返回元素的 r 长度子序列,允许单个元素重复多次。

组合按字典顺序排序。因此,如果对输入 iterable 进行排序,则将按排序顺序生成组合元组。

根据元素的位置而不是它们的值将它们视为唯一。因此,如果输入元素是唯一的,则生成的组合也将是唯一的。

来源:Python Docs

相关问题