Filtered product of lists without repetitions

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

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:

  1. import itertools
  2. def combinations(*all_lists):
  3. unique_combinations = set()
  4. for combo in itertools.product(*all_lists):
  5. if len(combo) == len(set(combo)):
  6. unique_combinations.add(tuple(sorted(combo)))
  7. 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:

  1. l1 = [1, 2, 3]
  2. l2 = [3, 4, 5]
  3. 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:

  1. import itertools
  2. def combinations(*all_lists: tuple[list[int]]):
  3. lists_product = itertools.product(*all_lists)
  4. res = set()
  5. for x in lists_product:
  6. if len(set(x)) == len(all_lists):
  7. x = tuple(sorted(x))
  8. res.add(x)
  9. return list(res)

I would appreciate any help.

答案1

得分: 1

以下是已翻译的内容:

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

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

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

  1. import random
  2. values = [1, 2, 3, 4, 5, 6, 7, 8, 9, 15, 20, 25, 30]
  3. l1 = random.choices(values, k=100)
  4. l2 = random.choices(values, k=100)
  5. res = combinations(l1, l2)
  6. res_2 = combinations_2(l1, l2)
  7. res_temp = sorted(res, key=lambda x: (x[0], x[1]))
  8. res_2_temp = sorted(res_2, key=lambda x: (x[0], x[1]))
  9. print(res_temp == res_2_temp)

这给出了以下结果:

True

然后是运行时间:

  1. %timeit combinations(l1, l2)

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

  1. %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 :

  1. def combinations_2(*all_lists: tuple[list[int]]):
  2. len_all_list = len(all_lists)
  3. lists_product = list(itertools.product(*all_lists))
  4. fset = set(map(frozenset,lists_product))
  5. list_filter = list(map(sorted, list(filter(lambda x: len(x) == len_all_list, fset))))
  6. res_2 = list(map(tuple, list_filter))
  7. 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.

  1. import random
  2. values = [1, 2, 3, 4, 5, 6, 7, 8, 9, 15, 20, 25, 30]
  3. l1 = random.choices(values,k=100)
  4. l2 = random.choices(values,k=100)
  5. res = combinations(l1, l2)
  6. res_2 = combinations_2(l1, l2)
  7. res_temp = sorted(res, key=lambda x: (x[0], x[1]))
  8. res_2_temp = sorted(res_2, key=lambda x: (x[0], x[1]))
  9. print(res_temp == res_2_temp)

Which gives the result

> True

Then the running time :

  1. %timeit combinations(l1, l2)

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

  1. %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:

确定