使用 itertools 排列和乘积 return 所有可能的字符排序

Using itertools permutations and product to return all possible character orderings

我在合并 itertools 排列和乘积以获得我想要的输出(列表)时遇到了一些困难。我正在尝试在考虑通配符字符 (?, *) 的情况下生成所有字符顺序。

例如,如果输入是 A?,我试图获得以下输出: AA AB 学士 空调 加州 广告 DA ...等

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

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)

将这两个部分组合起来(最有效)以获得我正在寻找的输出的最佳方法是什么?有没有更好、更有效的方法来做到这一点?

您可以只嵌套两个 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', '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)

在 python 3 中,使用 yield from 会简化一些。