Python 将开始索引添加到字符串索引生成器
我目前正在学习创建生成器和使用。所以我决定制作一个字符串索引生成器,但我想添加一些参数,比如“开始索引”,允许定义从何处开始生成索引 我提出了一个丑陋的解决方案,这个解决方案可能非常长,而且对于大索引来说效率不高:Python 将开始索引添加到字符串索引生成器,python,string,generator,itertools,Python,String,Generator,Itertools,我目前正在学习创建生成器和使用。所以我决定制作一个字符串索引生成器,但我想添加一些参数,比如“开始索引”,允许定义从何处开始生成索引 我提出了一个丑陋的解决方案,这个解决方案可能非常长,而且对于大索引来说效率不高: import itertools import string class StringIndex(object): ''' Generator that create string indexes in form: A, B, C ... Z, AA, AB
import itertools
import string
class StringIndex(object):
'''
Generator that create string indexes in form:
A, B, C ... Z, AA, AB, AC ... ZZ, AAA, AAB, etc.
Arguments:
- startIndex = string; default = ''; start increment for the generator.
- mode = 'lower' or 'upper'; default = 'upper'; is the output index in
lower or upper case.
'''
def __init__(self, startIndex = '', mode = 'upper'):
if mode == 'lower':
self.letters = string.ascii_lowercase
elif mode == 'upper':
self.letters = string.ascii_uppercase
else:
cmds.error ('Wrong output mode, expected "lower" or "upper", ' +
'got {}'.format(mode))
if startIndex != '':
if not all(i in self.letters for i in startIndex):
cmds.error ('Illegal characters in start index; allowed ' +
'characters are: {}'.format(self.letters))
self.startIndex = startIndex
def getIndex(self):
'''
Returns:
- string; current string index
'''
startIndexOk = False
x = 1
while True:
strIdMaker = itertools.product(self.letters, repeat = x)
for stringList in strIdMaker:
index = ''.join([s for s in stringList])
# Here is the part to simpify
if self.startIndex:
if index == self.startIndex:
startIndexOk = True
if not startIndexOk:
continue
###
yield index
x += 1
欢迎任何建议或改进。谢谢大家!
编辑:开始索引必须是字符串 您必须自己做算术(在base 26中),以避免在
itertools.product
上循环。但您至少可以设置x=len(self.startIndex)或1
旧(不正确)答案
如果不使用itertools(假设以一个字母开头),可以执行以下操作:
letters = 'abcdefghijklmnopqrstuvwxyz'
def getIndex(start, case):
lets = list(letters.lower()) if case == 'lower' else list(letters.upper())
# default is 'upper', but can also be an elif
for r in xrange(0,10):
for l in lets[start:]:
if l.lower() == 'z':
start = 0
yield ''.join(lets[:r])+l
我一直运行到最多创建10行字母,但您当然可以使用无限while循环,这样就可以永远调用它
正确答案
我以另一种方式找到了解决方案:我使用了一个基数为26的翻译器(基于(并且修复了,因为它不能完美地工作):)
我使用itertools.count()进行计数,并对所有可能性进行循环
守则:
import time
from itertools import count
def toAlph(x, letters):
div = 26
r = '' if x > 0 else letters[0]
while x > 0:
r = letters[x % div] + r
if (x // div == 1) and (x % div == 0):
r = letters[0] + r
break
else:
x //= div
return r
def getIndex(start, case='upper'):
alphabet = 'abcdefghijklmnopqrstuvwxyz'
letters = alphabet.upper() if case == 'upper' else alphabet
started = False
for num in count(0,1):
l = toAlph(num, letters)
if l == start:
started = True
if started:
yield l
iterator = getIndex('AA')
for i in iterator:
print(i)
time.sleep(0.1)
如果不清楚,很抱歉,但我希望开始索引是字符串。此外,如果索引大于25,则它似乎不起作用。最后,在“AZ”之后,我得到的是“ABA”而不是“BA”。对不起,我不太明白你的意思。考虑到这个问题,我想你可能需要一个递归生成器,因为你实际上是在一个无限深的树结构上循环。谢谢。还有一个问题。如果我从“AAZ”之后的索引开始,我会陷入一个无限循环。