Python 使用itertools置换和乘积返回所有可能的字符顺序
我在合并itertools排列和产品以获得我想要的输出(列表)方面有点困难。我正在尝试生成所有字符顺序,并考虑通配符(?,*) 例如,如果输入为?,我将尝试获得以下输出: AA AB 文学士 自动控制 加利福尼亚州 公元 爸爸。。。等 下面的代码很好地生成了所有排列,并保留了通配符Python 使用itertools置换和乘积返回所有可能的字符顺序,python,product,permutation,itertools,Python,Product,Permutation,Itertools,我在合并itertools排列和产品以获得我想要的输出(列表)方面有点困难。我正在尝试生成所有字符顺序,并考虑通配符(?,*) 例如,如果输入为?,我将尝试获得以下输出: AA AB 文学士 自动控制 加利福尼亚州 公元 爸爸。。。等 下面的代码很好地生成了所有排列,并保留了通配符 chars = "HELLO?" for i in range(len(chars)+1): perms = map(''.join, permutations(chars,i))
chars = "HELLO?"
for i in range(len(chars)+1):
perms = map(''.join, permutations(chars,i))
for perm in perms:
print(perm)
这段代码允许我用所有26个可能的字母字符替换通配符字符
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)
结合这两个部分(效率最高)以获得我想要的输出的最佳方法是什么?有更好、更有效的方法吗?您可以为循环嵌套两个
!如果需要,可以将值附加到列表中,但列表会很大;如果内存是一个问题,并且您只需要使用生成器一次值:
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个字母。此代码替换产品
(递归处理多个WILD)并消除重复项:
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', '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'} - 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)
在Python3中,使用yield from
可以简化一点。我遇到的一个问题发生在上面的代码中。如果你运行这个程序,它会在一个循环中打印出所有排列,每个排列有26个副本。如果我为“你好”运行这个,它会运行很长时间。即使是和“他”一起运行也需要一段时间。这也使我认为排列列表可以以更有效的方式构造。也许用一套或一本字典来剔除多余的烫发?这很奇怪。这段代码对我来说只需要0.0005秒,每次排列只打印2个(因为hello中有2'L)。你确定你使用的是itertools.permutation
?是的,我可以复制并粘贴上面的块,它运行大约5分钟,在perm\u with\u wild\u生成器打印语句中迭代26次。在这里试试?我只是更新了它以修复一个丢失的案例——现在有一些重复的案例,但比26个要少得多