我正在尝试生成动态字符集 CHAR_LIST
的每个组合,在 lower
和 upper
范围内。我粘贴在下面的代码有效,但我觉得它效率低得可怕,我想尽快完成。
例如,如果我想生成一个介于“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]
)。
接下来,我使用 enumerate
和 reversed
内置函数从右到左遍历字符串,跟踪我已经遍历了多少个字符.我认为这是关于您使用 i
和 new_dig
值所做的事情,但我认为它更清楚。 Python 中有很多有用的内置生成器!
最后,我使用了一个 break
语句提前退出了 for
循环,用一个 else
block 来处理我们到达的情况结束时没有 break
ing。当我第一次了解它时,循环中的这种 else
对我来说似乎毫无用处,但在这种情况下它确实很方便,其中循环的大部分运行将导致 break
语句被命中。
关于python - 生成具有重复的组合列表......有一个扭曲,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14616933/