Python 中可变数量的可预测 for 循环
Variable number of predictable for loops in Python
我正在尝试想出一种方法,从 20 个字符的字母表中生成所有可能的唯一字符串,其中字符串内的顺序无关紧要,并且字符串的长度可以变化。因此,例如,对于长度为 3 的字符串,可能的字符串将是 AAA
、AAB
、AAC
等,但不包括 BAA
或 CAA
。我想出了一种使用 itertools.product()
的方法,但它的计算成本非常高。最简单的方法就是使用嵌套的 for 循环。例如,要生成所有长度为四的字符串:
alphabet = ["A","C","D","E","F","G","H","I","K","L",
"M","N","P","Q","R","S","T","V","W","Y"]
combos = []
for a in range(len(alphabet)):
for b in range(a,len(alphabet)):
for c in range(b,len(alphabet)):
for d in range(c,len(alphabet)):
combos.append(alphabet[a] + alphabet[b] + alphabet[c] + alphabet[d])
现在,通过更改 for 循环的数量,可以轻松地为任何长度的字符串完成此操作。鉴于 for 循环序列本身是完全可以预测的,是否有方法可以简化此代码,而不是使用 if length == 3
运行 三个 for 循环和 if length == 4
运行 四个循环?我现在能想到的唯一方法是一堆 if-elif
语句:
if length == 3:
for a in range(len(alphabet)):
for b in range(a,len(alphabet)):
for c in range(b,len(alphabet)):
combos.append(alphabet[a] + alphabet[b] + alphabet[c])
elif length == 4:
for a in range(len(alphabet)):
for b in range(a,len(alphabet)):
for c in range(b,len(alphabet)):
for d in range(c,len(alphabet)):
combos.append(alphabet[a] + alphabet[b] + alphabet[c] + alphabet[d])
有没有比只覆盖一堆可能的长度值更简单的方法?
code for itertools.product 完全可以满足您的需求,并且比嵌套循环更有效
我怀疑你真正想要的是itertools.combinations_with_replacement
IIUC,你可以简单地使用itertools.combinations_with_replacement
。
>>> list(map(''.join, combinations_with_replacement(["a","b","c"],2)))
['aa', 'ab', 'ac', 'bb', 'bc', 'cc']
>>> list(map(''.join, combinations_with_replacement(["a","b","c"],3)))
['aaa', 'aab', 'aac', 'abb', 'abc', 'acc', 'bbb', 'bbc', 'bcc', 'ccc']
>>> list(map(''.join, combinations_with_replacement(alphabet,4))) == orig(alphabet)
True
(其中 orig
只是将您的原始代码包装到一个函数中)。
我正在尝试想出一种方法,从 20 个字符的字母表中生成所有可能的唯一字符串,其中字符串内的顺序无关紧要,并且字符串的长度可以变化。因此,例如,对于长度为 3 的字符串,可能的字符串将是 AAA
、AAB
、AAC
等,但不包括 BAA
或 CAA
。我想出了一种使用 itertools.product()
的方法,但它的计算成本非常高。最简单的方法就是使用嵌套的 for 循环。例如,要生成所有长度为四的字符串:
alphabet = ["A","C","D","E","F","G","H","I","K","L",
"M","N","P","Q","R","S","T","V","W","Y"]
combos = []
for a in range(len(alphabet)):
for b in range(a,len(alphabet)):
for c in range(b,len(alphabet)):
for d in range(c,len(alphabet)):
combos.append(alphabet[a] + alphabet[b] + alphabet[c] + alphabet[d])
现在,通过更改 for 循环的数量,可以轻松地为任何长度的字符串完成此操作。鉴于 for 循环序列本身是完全可以预测的,是否有方法可以简化此代码,而不是使用 if length == 3
运行 三个 for 循环和 if length == 4
运行 四个循环?我现在能想到的唯一方法是一堆 if-elif
语句:
if length == 3:
for a in range(len(alphabet)):
for b in range(a,len(alphabet)):
for c in range(b,len(alphabet)):
combos.append(alphabet[a] + alphabet[b] + alphabet[c])
elif length == 4:
for a in range(len(alphabet)):
for b in range(a,len(alphabet)):
for c in range(b,len(alphabet)):
for d in range(c,len(alphabet)):
combos.append(alphabet[a] + alphabet[b] + alphabet[c] + alphabet[d])
有没有比只覆盖一堆可能的长度值更简单的方法?
code for itertools.product 完全可以满足您的需求,并且比嵌套循环更有效
我怀疑你真正想要的是itertools.combinations_with_replacement
IIUC,你可以简单地使用itertools.combinations_with_replacement
。
>>> list(map(''.join, combinations_with_replacement(["a","b","c"],2)))
['aa', 'ab', 'ac', 'bb', 'bc', 'cc']
>>> list(map(''.join, combinations_with_replacement(["a","b","c"],3)))
['aaa', 'aab', 'aac', 'abb', 'abc', 'acc', 'bbb', 'bbc', 'bcc', 'ccc']
>>> list(map(''.join, combinations_with_replacement(alphabet,4))) == orig(alphabet)
True
(其中 orig
只是将您的原始代码包装到一个函数中)。