1

AAAAA00001 から ZZZZZ99999 までの昇順の連続した文字列を生成するより良い方法が必要ですか?

例:AAAAA00001、AAAAA00002、……。AAAAA99999、AAAAB00001、…。ZZZZZ99999

使用中の現在のサンプルは、次のように最適化されていません (私はそう感じます)。

def generateAlphanumericSequence():
    for i in range(65, 91):
        for j in range(65, 91):
            for k in range(65, 91):
                for l in range(65, 91):
                    for m in range(65, 91):
                        for z in range(1, 100000):
                            print '%s%s%s%s%s%05d' % (chr(i), chr(j), chr(k), chr(l), chr(m), z)

何か案は?

4

2 に答える 2

4

を使用しitertools.productます。

from string import ascii_uppercase
import itertools
def generateAlphanumericSequence():
    for i,j,k,l,m in itertools.product(ascii_uppercase,repeat=5):
         for z in range(1, 100000):
              yield '%s%s%s%s%s%05d' % (i, j, k, l, m, z)

これを簡単に一般化して、前に任意の数の文字を受け入れることができます (str.joinの出力を修正するために使用する場合itertools.product)。

from string import ascii_uppercase
import itertools
def generateAlphanumericSequence(repeat=5):
    for seq in itertools.product(ascii_uppercase,repeat=repeat):
         sseq = ''.join(seq)
         for z in range(1, 100000):
              yield '%s%05d' % (sseq, z)

%0?dもちろん、範囲にデフォルトの引数を使用することもできます。文字列を作成するために必要な桁数を計算するだけで済みますが、それは で取得できますmath.log10。例えば

fmtstring = '%s%0{size}d'.format(size=int(math.log10(rmax-1)+1))

数値部分に関するその他のオプションについては、私自身と @DSM のコメントを参照してください。そこにも最適化の機会があるかもしれません。あなたがする必要があり、見る必要がtimeitあります。

于 2012-10-26T12:43:26.447 に答える
1

基本的には 0 から 1188137599999 ((26 ** 5) * 100000 - 1) まで数えますが、100000 を超える値は 26 進数で文字のみで表されます。数値の書式設定をカウントから分離すると、次のようになります。

from string import ascii_uppercase

def _format(value, lettercount=5, digitcount=5):
    upper, lower = divmod(value, 10 ** digitcount)
    letters = []
    for i in xrange(lettercount):
        upper, val = divmod(upper, 26)
        letters.insert(0, ascii_uppercase[val])
    return '%s%0*i' % (''.join(letters), digitcount, lower)

def lettercounter(lettercount=5, digitcount=5):
   for i in xrange((26 ** lettercount) * (10 ** digitcount)):
       yield _format(i, lettercount, digitcount)

すべての値を 1 つずつ効率的に生成します。

デモ:

>>> lettercounter().next()
'AAAAA00000'
>>> _format(123456789)
'AABVM56789'
>>> _format(26**5*100000-1)
'ZZZZZ99999'

関数は、任意の数字と文字の長さも受け入れます。

>>> lettercounter(2, 2).next()
'AA00'

私の方法には、任意の数値を文字 + 数字のシーケンス番号にフォーマットし、0 から始まるシーケンスを生成できるという利点があります。文字シーケンスを生成するために使用itertools.productする場合、シーケンス番号の上半分を基数 26 の「数字」のセットに変換します。

于 2012-10-26T12:53:39.130 に答える