Filtered product of lists without repetitions

huangapple go评论70阅读模式
英文:

Filtered product of lists without repetitions

问题

I can help with that. Here's an improved implementation using itertools to find all combinations without repetitions of given lists efficiently:

import itertools

def combinations(*all_lists):
    unique_combinations = set()

    for combo in itertools.product(*all_lists):
        if len(combo) == len(set(combo)):
            unique_combinations.add(tuple(sorted(combo)))

    return list(unique_combinations)

这是一个使用itertools的改进实现,可以高效地找到给定列表的所有不重复组合。

英文:

I need an efficient solution to find all combinations without repetitions of a given lists. It has to work like this:

l1 = [1, 2, 3]
l2 = [3, 4, 5]
combinations(l1, l2) = [(2, 4), (3, 4), (1, 5), (1, 4), (2, 3), (2, 5), (1, 3), (3, 5)]

The important thing is that I could use it for an arbitrary number of lists and in a very efficient way (preferably using itertools).

My current implementation is way too slow:

import itertools

def combinations(*all_lists: tuple[list[int]]):
    lists_product = itertools.product(*all_lists)
    res = set()

    for x in lists_product:
        if len(set(x)) == len(all_lists):
            x = tuple(sorted(x))
            res.add(x)

    return list(res)

I would appreciate any help.

答案1

得分: 1

以下是已翻译的内容:

这里有一个稍微更快的解决方案:

def combinations_2(*all_lists: tuple[list[int]]):
    len_all_list = len(all_lists)
    lists_product = list(itertools.product(*all_lists))
    fset = set(map(frozenset, lists_product))
    list_filter = list(map(sorted, list(filter(lambda x: len(x) == len_all_list, fset))))
    res_2 = list(map(tuple, list_filter))
    return res_2

由于你的结果 res 来自一个无序数据结构 set(),所以我对两个输出进行了排序。

import random

values = [1, 2, 3, 4, 5, 6, 7, 8, 9, 15, 20, 25, 30]
l1 = random.choices(values, k=100)
l2 = random.choices(values, k=100)

res = combinations(l1, l2)
res_2 = combinations_2(l1, l2)

res_temp = sorted(res, key=lambda x: (x[0], x[1]))
res_2_temp = sorted(res_2, key=lambda x: (x[0], x[1]))

print(res_temp == res_2_temp)

这给出了以下结果:

True

然后是运行时间:

%timeit combinations(l1, l2)

7.1 ms ± 437 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

%timeit combinations_2(l1, l2)

2.56 ms ± 109 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

英文:

Here is a solution which is a little faster :

def combinations_2(*all_lists: tuple[list[int]]):
    len_all_list = len(all_lists)
    lists_product = list(itertools.product(*all_lists))
    fset = set(map(frozenset,lists_product))
    list_filter = list(map(sorted, list(filter(lambda x: len(x) == len_all_list, fset))))
    res_2 = list(map(tuple, list_filter))
    return res_2

As your result res is from a set() which is an unordered data structure. So I sorted the two outputs for comparing.

import random

values = [1, 2, 3, 4, 5, 6, 7, 8, 9, 15, 20, 25, 30]
l1 = random.choices(values,k=100)
l2 = random.choices(values,k=100)

res = combinations(l1, l2)
res_2 = combinations_2(l1, l2)

res_temp = sorted(res, key=lambda x: (x[0], x[1]))
res_2_temp = sorted(res_2, key=lambda x: (x[0], x[1]))

print(res_temp == res_2_temp)

Which gives the result

> True

Then the running time :

%timeit combinations(l1, l2)

> 7.1 ms ± 437 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

%timeit combinations_2(l1, l2)

> 2.56 ms ± 109 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

huangapple
  • 本文由 发表于 2023年6月29日 17:23:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/76579762.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定