簡體   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