python - 生成具有重复的组合列表......有一个扭曲

标签 python combinatorics

我正在尝试生成动态字符集 CHAR_LIST 的每个组合,在 lowerupper 范围内。我粘贴在下面的代码有效,但我觉得它效率低得可怕,我想尽快完成。

例如,如果我想生成一个介于“aab”和“zzz”之间且仅包含小写字母字符的列表,它将输出:['aab', 'aac', 'aad', ..., 'zzy', 'zzz']

如果有什么我不清楚的地方,请发表评论,我会澄清的。谢谢!

我现在的工作。

def generate_list(lower, upper):
    result = [lower]
    while lower != upper:
        if CHAR_LIST.index(lower[len(lower)-1:len(lower)]) + 1 < len(CHAR_LIST):
            lower = lower[:len(lower)-1] + CHAR_LIST[CHAR_LIST.index(lower[len(lower)-1:len(lower)]) + 1]
        else:
            new_lower = ""
            new_dig = 0
            inc_next = True
            for i in lower[::-1]:
                if i == CHAR_LIST[len(CHAR_LIST)-1] and inc_next:
                    new_lower += CHAR_LIST[0]
                    new_dig += 1
                else:
                    if inc_next:
                        inc_next = False
                        new_lower += CHAR_LIST[CHAR_LIST.index(i) + 1]
                    else:
                        new_lower += i
            if new_dig == len(lower):
                lower = str(CHAR_LIST[0])*int(len(lower)+1)
            else:
                lower = new_lower[::-1]
        result.append(lower)
    return result

编辑:我忘了补充,因为这是挑战的一部分,它还必须计算一个列表,该列表的起点和终点长度不同。例如,它还必须计算“a”和“zzz”之间的列表。很抱歉修改晚了,感谢到目前为止的创造性回答:)

最佳答案

我花了很长时间才理解你的代码是如何工作的,因为你做的工作比你需要的多得多。这是同一算法的激进“python 化”版本,我怀疑它会比您现在拥有的快很多:

def generate_strings(value, bound, alpha):
    yield value
    while value != bound: # run until we have reached bound
        for i, c in enumerate(reversed(value)): # loop over the string in reverse
            if c != alpha[-1]: # can this character be incremented?
                # construct an incremented value
                value = value[:-1-i] + alpha[alpha.index(c)+1] + alpha[0]*i
                break # exit the for loop
        else: # run only if for loop ended without breaking
            value = alpha[0]*(len(value) + 1) # make a longer string
        yield value

该函数是一个生成器,因此如果您需要列表结果,请将其传递给列表构造函数,如本例输出所示:

>>> print(list(generate_strings("b", "cc", "abcd")))
['b', 'c', 'd', 'aa', 'ab', 'ac', 'ad', 'ba', 'bb', 'bc', 'bd', 'ca', 'cb', 'cc']

我将字符序列作为函数的参数,而不是使用全局变量。 bound 参数也可以是 None 或其他一些无意义的值以获得无限生成器(但不要将其传递给 list() 没有缩短它!)。以下是这两个功能的示例:

>>> from itertools import islice
>>> from string import ascii_lowercase
>>>
>>> print(list(islice(generate_strings("xyzzy", None, ascii_lowercase), 5)))
['xyzzy', 'xyzzz', 'xzaaa', 'xzaab', 'xzaac']

如果您是 Python 新手,代码中完成的一些事情可能并不明显。

首先,我在字符串中使用了很多负索引。这从右边开始计数,以 -1 作为最右边的字符开始。仅此一项就可以大大简化您的代码(您有很多 x[len(x)-1])。

接下来,我使用 enumeratereversed 内置函数从右到左遍历字符串,跟踪我已经遍历了多少个字符.我认为这是关于您使用 inew_dig 值所做的事情,但我认为它更清楚。 Python 中有很多有用的内置生成器!

最后,我使用了一个 break 语句提前退出了 for 循环,用一个 else block 来处理我们到达的情况结束时没有 breaking。当我第一次了解它时,循环中的这种 else 对我来说似乎毫无用处,但在这种情况下它确实很方便,其中循环的大部分运行将导致 break 语句被命中。

关于python - 生成具有重复的组合列表......有一个扭曲,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14616933/

相关文章:

python - OpenCV Python : rotate image without cropping sides

python - 如何在不使用scipy的情况下计算python中的累积分布函数

postgresql - postgreSQL 中的组合学 - 选择对

algorithm - 组合学:分组字符挑战

c# - 组合总和

python - @property touch 有什么神奇的方法

python - 使用 AWS EMR 处理文件

python - Google App Engine - 创建文档编辑器/进入 Google 文档?

c# - 查找两个数组之间所有可能的值组合

c++ - 如何有效地找到数组中三元组和的最小差异?