使用 python itertools 生成自定义迭代
using python itertools to generate custom iteration
我知道通过使用itertools
,我们可以生成products
、permutations
和combinations
。但是,考虑以下情况:
max_allowed_len(sequence)= 3
iterable= ABC
repeat= 3 (or just `range(len('ABC')`)
我有兴趣通过重复 r 来生成具有 len(sequence)=0 len(sequence)=1 OR len(sequence)=2 and len(sequence)=3
的所有不同的 ABC 可迭代集。它有点奇怪的排列,重复允许不同的序列。所以我的 space 是:
3^0 + 3^1 + 3^2 + 3^3= 1 + 3 + 9+ 27= 40
谁能建议我如何在 python 甚至 c/c++ 中实现它?
例如:预期输出:
`'0'(无(序列长度 0))
长度为 1 的序列
'A'
'B'
'C'
长度为 2 的序列
'AA'
'BB'
'CC'
'AB'
'AC',...
长度为 3 的序列
'AAB'
'ABA'
'AAC'
'ACA'`
这还在继续。所以这里我的长度为 0、1、2 和 3(最大)。
这里有一个(相对)简单的方法来构造这样一个用于字符串输入的迭代器。它为空序列输出一个空字符串 ''
。我调用它两次以使输出更易于阅读。
函数的核心是一个生成器表达式循环,使用 product
和 repeat
arg 为每组长度从零到输入字符串长度的产品生成迭代器。这些迭代器随后由 chain.from_iterable
使用并提供给 ''.join
方法,使用 imap
实际调用由 product
生成的每个元组的方法。
from itertools import product, chain, imap
def all_prod(s):
return imap(''.join, chain.from_iterable(product(s, repeat=i) for i in range(len(s)+1)))
print(list(all_prod('ABC')))
for s in all_prod('abc'):
print(s)
输出
['', 'A', 'B', 'C', 'AA', 'AB', 'AC', 'BA', 'BB', 'BC', 'CA', 'CB', 'CC', 'AAA', 'AAB', 'AAC', 'ABA', 'ABB', 'ABC', 'ACA', 'ACB', 'ACC', 'BAA', 'BAB', 'BAC', 'BBA', 'BBB', 'BBC', 'BCA', 'BCB', 'BCC', 'CAA', 'CAB', 'CAC', 'CBA', 'CBB', 'CBC', 'CCA', 'CCB', 'CCC']
a
b
c
aa
ab
ac
ba
bb
bc
ca
cb
cc
aaa
aab
aac
aba
abb
abc
aca
acb
acc
baa
bab
bac
bba
bbb
bbc
bca
bcb
bcc
caa
cab
cac
cba
cbb
cbc
cca
ccb
ccc
FWIW,这是使用普通 chain
函数的替代版本;它使用额外的循环而不是 imap
,因此它可能效率较低,但我想它也可能更容易理解。
def all_prod(s):
return (''.join(v) for u in chain(product(s, repeat=i) for i in range(len(s)+1)) for v in u)
我知道通过使用itertools
,我们可以生成products
、permutations
和combinations
。但是,考虑以下情况:
max_allowed_len(sequence)= 3
iterable= ABC
repeat= 3 (or just `range(len('ABC')`)
我有兴趣通过重复 r 来生成具有 len(sequence)=0 len(sequence)=1 OR len(sequence)=2 and len(sequence)=3
的所有不同的 ABC 可迭代集。它有点奇怪的排列,重复允许不同的序列。所以我的 space 是:
3^0 + 3^1 + 3^2 + 3^3= 1 + 3 + 9+ 27= 40
谁能建议我如何在 python 甚至 c/c++ 中实现它?
例如:预期输出:
`'0'(无(序列长度 0))
长度为 1 的序列
'A'
'B'
'C'
长度为 2 的序列
'AA'
'BB'
'CC'
'AB'
'AC',...
长度为 3 的序列
'AAB'
'ABA'
'AAC'
'ACA'`
这还在继续。所以这里我的长度为 0、1、2 和 3(最大)。
这里有一个(相对)简单的方法来构造这样一个用于字符串输入的迭代器。它为空序列输出一个空字符串 ''
。我调用它两次以使输出更易于阅读。
函数的核心是一个生成器表达式循环,使用 product
和 repeat
arg 为每组长度从零到输入字符串长度的产品生成迭代器。这些迭代器随后由 chain.from_iterable
使用并提供给 ''.join
方法,使用 imap
实际调用由 product
生成的每个元组的方法。
from itertools import product, chain, imap
def all_prod(s):
return imap(''.join, chain.from_iterable(product(s, repeat=i) for i in range(len(s)+1)))
print(list(all_prod('ABC')))
for s in all_prod('abc'):
print(s)
输出
['', 'A', 'B', 'C', 'AA', 'AB', 'AC', 'BA', 'BB', 'BC', 'CA', 'CB', 'CC', 'AAA', 'AAB', 'AAC', 'ABA', 'ABB', 'ABC', 'ACA', 'ACB', 'ACC', 'BAA', 'BAB', 'BAC', 'BBA', 'BBB', 'BBC', 'BCA', 'BCB', 'BCC', 'CAA', 'CAB', 'CAC', 'CBA', 'CBB', 'CBC', 'CCA', 'CCB', 'CCC']
a
b
c
aa
ab
ac
ba
bb
bc
ca
cb
cc
aaa
aab
aac
aba
abb
abc
aca
acb
acc
baa
bab
bac
bba
bbb
bbc
bca
bcb
bcc
caa
cab
cac
cba
cbb
cbc
cca
ccb
ccc
FWIW,这是使用普通 chain
函数的替代版本;它使用额外的循环而不是 imap
,因此它可能效率较低,但我想它也可能更容易理解。
def all_prod(s):
return (''.join(v) for u in chain(product(s, repeat=i) for i in range(len(s)+1)) for v in u)