使列表中所有可能的值组合大小不同

Make all possible combinations of values from lists different size

我有一个 Python dict,其中包含不同长度的列表作为键值。

{
    'basis1': ['key11', 'key12', 'key13', 'key14'],
    'basis2': ['key21'],
    'basis3': ['key31', 'key32', 'key33'],
    'basis4': ['key41', 'key42'],
    ...'basisX': ['keyX1', ..., 'keyXX']
}

如何获得所有 dict 键值的所有可能组合(每个键的一个值到另一个键的一个值)?我的意思不仅是“basis1 + basis2 + ... basisX”值,还有例如“basis2 + basis1 + basis3”和“basis3 + basisX”值。

我曾经使用“itertools”中的“product”函数进行迭代,以通过预定公式生成关键字。但由于公式和这些公式中的列表数量,存在限制。但我需要做到这一点,它不依赖于将被馈送到函数输入的列表的数量,以及以不同的顺序混合列表中的值。

from itertools import product
...
...
...
# Each [keysX] is a list of values

    formula1 = [keys0] + [keys1]
    formula2 = [keys0] + [keys2]
    formula3 = [keys1] + [keys2]
    formula4 = [keys0] + [keys1] + [keys2]
    all_keywords = []

    for combo in product(*formula1):
        all_keywords.append(" ".join(combo))

    for combo in product(*formula2):
        all_keywords.append(" ".join(combo))

    for combo in product(*formula3):
        all_keywords.append(" ".join(combo))

    for combo in product(*formula4):
        all_keywords.append(" ".join(combo))

注意:考虑到它是一个幂集所有元素的排列,由此产生的可迭代对象将是巨大的。所以建议,除非必要,否则不要将其存储在内存中。出于这个原因,我使用了 generators

您可以使用以下内容:

from itertools import chain, combinations, permutations

def powerset(iterable):
    '''
    >>> list(powerset([1, 2, 3]))
    [(1,) (2,) (3,) (1,2) (1,3) (2,3) (1,2,3)]
    '''
    iterable = list(iterable)
    return chain.from_iterable(
        combinations(iterable, r)
        for r, _ in enumerate(iterable, start=1)
    )

def perm_powerset(iterable):
    '''
    Given a powerset, returns a generator consisting
    all possible permutations of each element in the powerset.
    '''
    for each_set in powerset(iterable):
        for elem in permutations(each_set):
            yield elem

d = {'k1': [1, 2], 'k2': [3], 'k4': [4]}

for elem in perm_powerset(chain.from_iterable(d.values())):
    print(elem)

输出:

(1,)
(2,)
(3,)
(4,)
(1, 2)
(2, 1)
(1, 3)
(3, 1)
(1, 4)
(4, 1)
(2, 3)
(3, 2)
(2, 4)
(4, 2)
(3, 4)
(4, 3)
(1, 2, 3)
(1, 3, 2)
(2, 1, 3)
(2, 3, 1)
(3, 1, 2)
(3, 2, 1)
(1, 2, 4)
(1, 4, 2)
(2, 1, 4)
(2, 4, 1)
(4, 1, 2)
(4, 2, 1)
(1, 3, 4)
(1, 4, 3)
(3, 1, 4)
(3, 4, 1)
(4, 1, 3)
(4, 3, 1)
(2, 3, 4)
(2, 4, 3)
(3, 2, 4)
(3, 4, 2)
(4, 2, 3)
(4, 3, 2)
(1, 2, 3, 4)
(1, 2, 4, 3)
(1, 3, 2, 4)
(1, 3, 4, 2)
(1, 4, 2, 3)
(1, 4, 3, 2)
(2, 1, 3, 4)
(2, 1, 4, 3)
(2, 3, 1, 4)
(2, 3, 4, 1)
(2, 4, 1, 3)
(2, 4, 3, 1)
(3, 1, 2, 4)
(3, 1, 4, 2)
(3, 2, 1, 4)
(3, 2, 4, 1)
(3, 4, 1, 2)
(3, 4, 2, 1)
(4, 1, 2, 3)
(4, 1, 3, 2)
(4, 2, 1, 3)
(4, 2, 3, 1)
(4, 3, 1, 2)
(4, 3, 2, 1)

这段代码生成了你需要的东西。首先,您需要拥有所有值的组合,然后为每个组合生成关键字的所有产品。

from itertools import product, chain, combinations

my_dict = {
    'basis1': ['key11', 'key12', 'key13', 'key14'],
    'basis2': ['key21'],
    'basis3': ['key31', 'key32', 'key33'],
    'basis4': ['key41', 'key42']}

list_of_values = list(my_dict.values())

all_combs_of_lists = [combinations(list_of_values, r) for r in range(1, len(list_of_values) + 1)]
list_combinations = list(chain.from_iterable(all_combs_of_lists))

all_keywords = [" ".join(combo) for item in list_combinations for combo in product(*item)]
        
print(all_keywords)

输出:

['key11', 'key12', 'key13', 'key14', 'key21', 'key31', 'key32', 'key33', 'key41', 'key42', 'key11 key21', 'key12 key21', 'key13 key21', 'key14 key21', 'key11 key31', 'key11 key32', 'key11 key33', 'key12 key31', 'key12 key32', 'key12 key33', 'key13 key31', 'key13 key32', 'key13 key33', 'key14 key31', 'key14 key32', 'key14 key33', 'key11 key41', 'key11 key42', 'key12 key41', 'key12 key42', 'key13 key41', 'key13 key42', 'key14 key41', 'key14 key42', 'key21 key31', 'key21 key32', 'key21 key33', 'key21 key41', 'key21 key42', 'key31 key41', 'key31 key42', 'key32 key41', 'key32 key42', 'key33 key41', 'key33 key42', 'key11 key21 key31', 'key11 key21 key32', 'key11 key21 key33', 'key12 key21 key31', 'key12 key21 key32', 'key12 key21 key33', 'key13 key21 key31', 'key13 key21 key32', 'key13 key21 key33', 'key14 key21 key31', 'key14 key21 key32', 'key14 key21 key33', 'key11 key21 key41', 'key11 key21 key42', 'key12 key21 key41', 'key12 key21 key42', 'key13 key21 key41', 'key13 key21 key42', 'key14 key21 key41', 'key14 key21 key42', 'key11 key31 key41', 'key11 key31 key42', 'key11 key32 key41', 'key11 key32 key42', 'key11 key33 key41', 'key11 key33 key42', 'key12 key31 key41', 'key12 key31 key42', 'key12 key32 key41', 'key12 key32 key42', 'key12 key33 key41', 'key12 key33 key42', 'key13 key31 key41', 'key13 key31 key42', 'key13 key32 key41', 'key13 key32 key42', 'key13 key33 key41', 'key13 key33 key42', 'key14 key31 key41', 'key14 key31 key42', 'key14 key32 key41', 'key14 key32 key42', 'key14 key33 key41', 'key14 key33 key42', 'key21 key31 key41', 'key21 key31 key42', 'key21 key32 key41', 'key21 key32 key42', 'key21 key33 key41', 'key21 key33 key42', 'key11 key21 key31 key41', 'key11 key21 key31 key42', 'key11 key21 key32 key41', 'key11 key21 key32 key42', 'key11 key21 key33 key41', 'key11 key21 key33 key42', 'key12 key21 key31 key41', 'key12 key21 key31 key42', 'key12 key21 key32 key41', 'key12 key21 key32 key42', 'key12 key21 key33 key41', 'key12 key21 key33 key42', 'key13 key21 key31 key41', 'key13 key21 key31 key42', 'key13 key21 key32 key41', 'key13 key21 key32 key42', 'key13 key21 key33 key41', 'key13 key21 key33 key42', 'key14 key21 key31 key41', 'key14 key21 key31 key42', 'key14 key21 key32 key41', 'key14 key21 key32 key42', 'key14 key21 key33 key41', 'key14 key21 key33 key42']