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

Posted

技术标签:

【中文标题】使列表中所有可能的值组合大小不同【英文标题】:Make all possible combinations of values from lists different size 【发布时间】:2021-11-24 10:35:35 【问题描述】:

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


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

如何获得所有 dict 键值的所有可能组合(每个键的一个值与另一个键的一个值)?我的意思不仅是“基础1 +基础2 + ...基础X”值,还有例如“basis2 + basis1 + basic3”和“basis3 + basicX”值。

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

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))

【问题讨论】:

对于这样的问题,我很难理解。也许输入和预期输出部分会帮助我和其他人更好地理解它。 你可能想看看powersets。转到itertools recipe,搜索powerset @SayanipDutta powerset 将返回 (1,) (​​2,) (3,) (1,2) (1,3) (2,3) (1,2,3),但没有(2, 1) 或 (3, 1, 2) 值 @kite 输出:key11 + key31 + keyXX keyXX + key21 key12 + key32 + key42 + keyX1 以此类推。我需要所有可能的值,但 itertools 产品不会打乱值顺序以创建唯一组合。另外,它会创建all-to-all组合或者我们需要为组合指定公式,这在大量列表的情况下会出现问题。 当然,在powerset之后你需要permutate每个元素。 【参考方案1】:

注意:考虑到它是一个幂集的所有元素的排列,因此产生的可迭代将是巨大的。因此建议,除非必要,否则不要将其存储在内存中。为此,我使用了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)

【讨论】:

谢谢。这解决了我的问题【参考方案2】:

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

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']

【讨论】:

以上是关于使列表中所有可能的值组合大小不同的主要内容,如果未能解决你的问题,请参考以下文章

Excel VBA 宏生成可能组合的列表

如何让组合框选择与 ExtJS6 中显示的值不同的值?

k 大小 p 的不同组合,无需替换

使用java流将两个相同大小(和不同类型)的列表组合到域对象列表中

如何从以前的值生成中获取不同的十六进制值?

从包含不同长度子列表的列表中构造所有组合