【问题标题】:n-fold Cartesian product on a single list in Python [duplicate]Python中单个列表上的n倍笛卡尔积[重复]
【发布时间】:2020-10-06 14:57:49
【问题描述】:

如何在 Pyhton 中以优雅(简洁)的方式计算列表上的 n 倍笛卡尔积,即 A × ... × A(n 次)?

此问题与Get the cartesian product of a series of lists? 不重复。我不希望一系列列表的笛卡尔积相互交叉。我希望单个列表的笛卡尔积与自身交叉 n 次,其中 n 是给函数的参数。

例子:

l = ["a", "b", "c"]
> cart_prod(l, 0)
[]
> cart_prod(l, 1)
[('a',), ('b',), ('c',)]
> cart_prod(l, 2)
[('a', 'a'), ('a', 'b'), ('a', 'c'), ('b', 'a'), ('b', 'b'), ('b', 'c'), ('c', 'a'), ('c', 'b'), ('c', 'c')]
> cart_prod(l, 3)
[('a', 'a', 'a'), ('a', 'a', 'b'), ('a', 'a', 'c'), ('a', 'b', 'a'), ('a', 'b', 'b'), ('a', 'b', 'c'), ('a', 'c', 'a'), ('a', 'c', 'b'), ('a', 'c', 'c'), ('b', 'a', 'a'), ('b', 'a', 'b'), ('b', 'a', 'c'), ('b', 'b', 'a'), ('b', 'b', 'b'), ('b', 'b', 'c'), ('b', 'c', 'a'), ('b', 'c', 'b'), ('b', 'c', 'c'), ('c', 'a', 'a'), ('c', 'a', 'b'), ('c', 'a', 'c'), ('c', 'b', 'a'), ('c', 'b', 'b'), ('c', 'b', 'c'), ('c', 'c', 'a'), ('c', 'c', 'b'), ('c', 'c', 'c')]

我想出了以下迭代解决方案:

def cart_prod(l, n):
    if n == 0:
        return []  # compute the result for n = 0
    # preliminarily, create a list of lists instead of a list of tuples
    res = [[x] for x in l]  # initialize list with singleton tuples (n = 1)
    for i in range(n-1):
        res = [r + [x] for r in res for x in l]  # concatenate each n-1 tuple with each element from a
    res = [tuple(el) for el in res]  # turn the list of lists into a list of tuples
    return res

这段代码可以完成这项工作,但是否有更短的、可能单行的定义,可能是嵌套列表理解或 lambda 表达式?我对更紧凑的解决方案感兴趣,不一定是更具可读性的解决方案。

【问题讨论】:

  • 它在我看来仍然是重复的。只需复制列表,然后使用itertools.product
  • 更好的是,itertools.tee 列表n 次,然后使用itertools.product
  • @bnaecker 你不需要tee
  • @chepner 不错,我以前从未使用过那个 kwarg。

标签: python cartesian-product


【解决方案1】:

itertools.product 采用关键字参数来指示应该重复给定的参数。

>>> from itertools import product
>>> list(product([1,2], repeat=0))
[()]
>>> list(product([1,2], repeat=1))
[(1,), (2,)]
>>> list(product([1,2], repeat=2))
[(1, 1), (1, 2), (2, 1), (2, 2)]

这也适用于多个迭代。

# Equivalent to list(product([1,2], ['a', 'b'], [1,2], ['a', 'b']))
>>> list(product([1,2], ['a', 'b'], repeat=2))
[(1, 'a', 1, 'a'), (1, 'a', 1, 'b'), (1, 'a', 2, 'a'), (1, 'a', 2, 'b'), (1, 'b', 1, 'a'), (1, 'b', 1, 'b'), (1, 'b', 2, 'a'), (1, 'b', 2, 'b'), (2, 'a', 1, 'a'), (2, 'a', 1, 'b'), (2, 'a', 2, 'a'), (2, 'a', 2, 'b'), (2, 'b', 1, 'a'), (2, 'b', 1, 'b'), (2, 'b', 2, 'a'), (2, 'b', 2, 'b')]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-02-24
    • 1970-01-01
    • 2020-02-19
    • 1970-01-01
    • 1970-01-01
    • 2013-10-29
    • 2013-07-14
    相关资源
    最近更新 更多