Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用itertools置换和乘积返回所有可能的字符顺序_Python_Product_Permutation_Itertools - Fatal编程技术网

Python 使用itertools置换和乘积返回所有可能的字符顺序

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))

我在合并itertools排列和产品以获得我想要的输出(列表)方面有点困难。我正在尝试生成所有字符顺序,并考虑通配符(?,*)

例如,如果输入为?,我将尝试获得以下输出: AA AB 文学士 自动控制 加利福尼亚州 公元 爸爸。。。等

下面的代码很好地生成了所有排列,并保留了通配符

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个要少得多