有重复的笛卡尔积
Descartes product with repetition
所以我想做一个接受正整数 n
和 returns 一堆 n-tuples
[ 的函数=30=],填入True/False (1/0)
所有可能的组合,例如:
f(1) = (0,),(1,)
f(2) = (0, 0), (0, 1), (1, 0), (1, 1)
我的代码是:
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))
我听说 python 递归不是很好,并且通常认为这不是有效的解决方案。
似乎使用给定数字范围内的 powerset(powerset 的配方来自 itertools
模块)然后使用某种 Indicator function 就可以了。
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))
然而,对于一个非常基本的东西来说,似乎工作量太大了。
有更好的方法吗?
您描述的不是幂集,而是笛卡尔重复积。使用 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)]
所以我想做一个接受正整数 n
和 returns 一堆 n-tuples
[ 的函数=30=],填入True/False (1/0)
所有可能的组合,例如:
f(1) = (0,),(1,)
f(2) = (0, 0), (0, 1), (1, 0), (1, 1)
我的代码是:
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))
我听说 python 递归不是很好,并且通常认为这不是有效的解决方案。
似乎使用给定数字范围内的 powerset(powerset 的配方来自 itertools
模块)然后使用某种 Indicator function 就可以了。
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))
然而,对于一个非常基本的东西来说,似乎工作量太大了。 有更好的方法吗?
您描述的不是幂集,而是笛卡尔重复积。使用 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)]