Python中一组列表的所有可能排列

68
在Python中我有一个包含n个列表的列表,每个列表都有可变数量的元素。如何创建一个包含所有可能排列的单个列表:
例如:
[ [ a, b, c], [d], [e, f] ]

我想要

[ [a, d, e] , [a, d, f], [b, d, e], [b, d, f], [c, d, e], [c, d, f] ]

注意我事先不知道n的值。我认为itertools.product是正确的方法,但它要求我事先知道参数的数量。


我不明白——为什么你不数一下列表来找到n? - user24359
3
我可以做到,这对我有什么帮助? - Ian Davis
4个回答

121

使用 itertools.product 不需要提前知道 n 的值。

>>> import itertools
>>> s=[ [ 'a', 'b', 'c'], ['d'], ['e', 'f'] ]
>>> list(itertools.product(*s))
[('a', 'd', 'e'), ('a', 'd', 'f'), ('b', 'd', 'e'), ('b', 'd', 'f'), ('c', 'd', 'e'), ('c', 'd', 'f')]

是的 - 在Python中,参数列表非常方便。 - Amber
关于参数列表的更多信息请参考:http://docs.python.org/tutorial/controlflow.html#arbitrary-argument-lists - Amber
太好了。我一直不知道如何正确使用参数列表。 - Ian Davis
5
一看就会,一击即中,十分顺手。这就是我喜爱Python的原因! - makra
雄辩。没错,Python很美。 - mikkokotila

7

您可以使用多层列表推导来完成:

>>> L1=['a','b','c']
>>> L2=['d']
>>> L3=['e','f']
>>> [[i,j,k] for i in L1 for j in L2 for k in L3]
[['a', 'd', 'e'], ['a', 'd', 'f'], ['b', 'd', 'e'], ['b', 'd', 'f'], ['c', 'd', 'e'], ['c', 'd', 'f']]

5
这需要你事先知道数字“n”的值(在你的答案中,n = 3) :) - badp
谢谢,但我不知道列表的数量。我有[L1,L2,L3,...]的等价物。 - Ian Davis
啊,好的,我之前对于你所说的“提前知道参数数量”有些不清楚——我以为你可能是指列表的长度。 - Daniel DiPaolo

6

itertools.product 对我很有用。

>>> l=[ [ 1, 2, 3], [4], [5, 6] ]
>>> list(itertools.product(*l))
[(1, 4, 5), (1, 4, 6), (2, 4, 5), (2, 4, 6), (3, 4, 5), (3, 4, 6)]
>>> l=[ [ 1, 2, 3], [4], [5, 6],[7,8] ]
>>> list(itertools.product(*l))
[(1, 4, 5, 7), (1, 4, 5, 8), (1, 4, 6, 7), (1, 4, 6, 8), (2, 4, 5, 7), (2, 4, 5, 8), (2, 4, 6, 7), (2, 4, 6, 8), (3, 4, 5, 7), (3, 4, 5, 8), (3, 4, 6,
 7), (3, 4, 6, 8)]
>>>

0

如果出于某种原因,您需要定义自己的方法而不使用{{link1:itertools.product}}(例如,面试问题):

from typing import Any, Optional

def cartesian_product(values: list[list[Any]],
                      partial_result: Optional[list[Any]] = None,
                      result: Optional[list[list[Any]]] = None) -> list[list[Any]]:
    """
    Computes the cartesian product of a list of lists. This function is a 
    recursive implementation and gives the same output as the function 
    itertools.product() from the Python standard library.

    :param values: A list of lists for which the cartesian product is computed.
    :param partial_result: A list that accumulates the current combination of values. 
                           This parameter is mainly used during the recursion.
    :param result: A list of all combinations that have been considered so far. 
                   This parameter is mainly used during the recursion.
    :return: A list of lists, where each inner list is one combination of 
             elements from the input lists.
    """
    if partial_result is None:
        partial_result = []
    if result is None:
        result = []
    if values:
        for v in values[0]:
            cartesian_product(values[1:], partial_result + [v], result)
    else:
        result.append(partial_result)
    return result

print(f"{cartesian_product([['a', 'b', 'c'], ['d'], ['e', 'f']]) = }")
print(f"{cartesian_product([[1, 2, 3], [4], [5, 6]]) = }")

输出:

cartesian_product([['a', 'b', 'c'], ['d'], ['e', 'f']]) = [['a', 'd', 'e'], ['a', 'd', 'f'], ['b', 'd', 'e'], ['b', 'd', 'f'], ['c', 'd', 'e'], ['c', 'd', 'f']]
cartesian_product([[1, 2, 3], [4], [5, 6]]) = [[1, 4, 5], [1, 4, 6], [2, 4, 5], [2, 4, 6], [3, 4, 5], [3, 4, 6]]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接