问题描述
我在合并 itertools 排列和产品以获得我想要的输出(列表)时遇到了一些困难。我正在尝试生成所有字符的排序,并考虑通配符 (?,*)。
例如,如果输入是 A?,我试图获得以下输出: 机管局 AB 文学士 交流电 认证机构 广告 DA ...等
chars = "HELLO?"
for i in range(len(chars)+1):
perms = map(''.join,permutations(chars,i))
for perm in perms:
print(perm)
chars = "HELLO?"
wilds = [('A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z') if char == "?" else (char) for char in chars]
for p in itertools.product(*wilds):
print(p)
结合这两个部分(最有效)以获得我正在寻找的输出的最佳方法是什么?有没有更好、更有效的方法来做到这一点?
解决方法
您可以嵌套两个 for
循环!如果需要,将值附加到列表中,但它会很大;如果内存是一个问题,并且您只需要使用生成器后的值:
import itertools
def perm_with_wild_generator(chars):
wilds = [('A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z') if char == "?" else (char) for char in chars]
for p in itertools.product(*wilds):
for i in range(len(p) + 1):
perms = map(''.join,itertools.permutations(p,i))
for perm in perms:
yield perm
for c in perm_with_wild_generator("HELLO?"):
print(c)
您在评论中提到的重复项是因为 itertools.product
的输出分别排列了它们的字母的 5/6。此代码替换 product
(递归处理多个通配符)并消除重复项:
import itertools
def replace_wild(chars,wilds):
if '?' not in chars:
yield chars
else:
for wild in wilds:
for w in replace_wild(chars.replace("?",wild,1),wilds):
yield w
def perm_with_wild_generator(chars):
wilds = {'A','Z'} - set(chars)
for i in range(len(chars) + 1):
perms = map(''.join,itertools.permutations(chars,i))
for perm in perms:
for w in replace_wild(perm,wilds | set(perm.replace('?',""))):
yield w
for c in perm_with_wild_generator("HELLO?"):
print(c)
在 python 3 中,使用 yield from
会简化一些。