笛卡尔产品重复

Rob*_*Rob 0 python combinatorics python-3.x

所以我想创建一个带正整数n并返回一堆的函数n-tuples,填充所有可能的组合True/False (1/0),例如:

f(1) = (0,),(1,)


f(2) = (0, 0), (0, 1), (1, 0), (1, 1)
Run Code Online (Sandbox Code Playgroud)

我的代码是:

def fill(n: int) -> Tuple[Tuple[int]]:
    if n == 1:
        return (0,),(1,)
    return tuple((i + j) for i in fill(n-1) for j in fill(1))
Run Code Online (Sandbox Code Playgroud)

我听说python不太适合递归,一般觉得这不是有效的解决方案.

看起来像使用给定数量范围的powerset(powerset的配方来自itertools模块)然后使用某种指示器功能就可以做到这一点.

from itertools import chain, combinations

def range_powerset(n: int):
    s = list(range(n))
    return chain.from_iterable(combinations(s, r) for r in range(len(s)+1))

def indicator(A: Iterable, B: Iterable):
    return tuple(i in A for i in B)

def fill2(n: int):
    return (indicator(i, range(n)) for i in range_powerset(n))
Run Code Online (Sandbox Code Playgroud)

然而,对于一个非常基本的东西来说似乎太过分了.有没有更好的方法呢?

Tam*_*dus 8

你描述的不是一个powerset而是一个重复的笛卡尔产品.用途itertools.product:

import itertools
def fill(n):
    return itertools.product((0,1), repeat=n)

print(list(fill(3)))

# [(0, 0, 0), (0, 0, 1), (0, 1, 0), (0, 1, 1), (1, 0, 0), (1, 0, 1), (1, 1, 0), (1, 1, 1)]
Run Code Online (Sandbox Code Playgroud)