繁体   English   中英

如何使用 n 个列表的每个列表中的单个元素查找 k 大小元组的所有唯一组合

[英]How to find all unique combinations of k size tuple using a single element from each list of n lists

给定一个包含 N 个多个长度的子列表的列表,找到所有 k 大小的唯一组合,从每个子列表中只选择一个元素。

  • 组合中元素的顺序无关紧要:(a, b) = (b, a)

sample_k = 2

sample_list = [['B1','B2','B3'], ['T1','T2'], ['L1','L2','L3','L4']]

expected_output =
[
('B1', 'T1'),('B1', 'T2'),('B1', 'L1'),('B1', 'L2'),('B1', 'L3'),('B1', 'L4'),
('B2', 'T1'),('B2', 'T2'),('B2', 'L1'),('B2', 'L2'),('B2', 'L3'),('B2', 'L4'),
('B3', 'T1'),('B3', 'T2'),('B3', 'L1'),('B3', 'L2'),('B3', 'L3'),('B3', 'L4'),
('T1', 'L1'),('T1', 'L2'),('T1', 'L3'),('T1', 'L4'),
('T2', 'L1'),('T2', 'L2'),('T2', 'L3'),('T2', 'L4')
]
  • pythonic 方式的加分
  • 速度/效率很重要,这个想法是在一个包含数百个列表的列表中使用,列表的长度从 5 到 50 不等

到目前为止我已经能够完成的事情:使用 for 和 while 循环移动指针并构建答案,但是我很难弄清楚如何包含 K 参数来动态设置元组组合的大小。 (真的不是很开心)

def build_combinations(lst):
    result = []
    count_of_lst = len(lst)
    for i, sublist in enumerate(lst):
        if i == count_of_lst - 1:
            continue
        else:
            for item in sublist:
                j = 0
                while i < len(lst)-1:
                    while j <= len(lst[i+1])-1:
                        comb = (item, lst[i+1][j])
                        result.append(comb)
                        j = j + 1
                    i = i + 1
                    j = 0
                i = 0
    return result

我在堆栈溢出中看到过许多类似的问题,但没有一个以我尝试的方式解决参数(每个列表中的一个项目,组合的大小是函数的参数)

我尝试使用 itertools 组合、乘积、排列并翻转它们,但没有成功。 每当使用 itertools 时,我要么很难只使用每个列表中的一个项目,要么无法设置我需要的元组的大小。

我尝试了 NumPy 使用 arrays 和更多的数学/矩阵方法,但没有 go 太远。 肯定有解决 NumPy 的方法,因此我也标记了 numpy

您需要组合两个itertools助手, combinations到 select 两个唯一的有序list以使用,然后product以组合两者的元素:

from itertools import combinations, product

sample_k = 2

sample_list = [['B1','B2','B3'], ['T1','T2'], ['L1','L2','L3','L4']]

expected_output = [pair
                   for lists in combinations(sample_list, sample_k)
                   for pair in product(*lists)]
print(expected_output)

在线试用!

如果你真的想变得花哨/聪明/丑陋,你可以将所有工作推到 C 层:

from itertools import combinations, product, starmap, chain

sample_k = 2

sample_list = [['B1','B2','B3'], ['T1','T2'], ['L1','L2','L3','L4']]

expected_output = list(chain.from_iterable(starmap(product, combinations(sample_list, sample_k))))
print(expected_output)

对于巨大的输入,这几乎肯定会运行得更快(特别是如果你可以直接从chain.from_iterable循环结果而不是将它们实现为list ),但它可能不值得丑陋,除非你真的很紧张周期(我会期望速度提高 10% 以上,但您需要进行基准测试才能确定)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM