2017-02-07 3 views
2

J'ai créé une fonction qui génère une liste d'alphabets incrémentés en continu. A, B, C ..., Z. Après Z, il va à AA, AB, AC ... AZ. Ce motif se répète. Ceci est similaire aux noms de colonnes MS Excel. À l'heure actuelle, cette fonction génère une liste finie d'alphabets. Je peux ensuite itérer en même temps avec une liste finie, par ex. 0-10. Voir mon code ci-dessous. Ce que j'aimerais, c'est créer un générateur qui me donnera une liste infiniment longue d'alphabets incrémentés.Comment créer un itérateur infini pour générer un modèle d'alphabet incrémenté?

import string 


def _column_name_generator(): 
    column_names = [] 
    for x in range(0, 100): 
     if x < 26: 
      column_names.append(string.ascii_uppercase[x % 26]) 
     else: 
      column_names.append(column_names[x/26 - 1] + string.ascii_uppercase[x % 26]) 
    return column_names 

container = [] 
for column_name, num in zip(_column_name_generator(), range(0, 10)): 
    container.append(column_name + str(num)) 

print _column_name_generator() 
print container 

container = ['A0', 'B1', 'C2', 'D3', 'E4', 'F5', 'G6', 'H7', 'I8', 'J9'] 
+0

explorons au sujet' yield' –

Répondre

6

Rendement dernier élément d » column_names à chaque fois, et utiliser itertools.count au lieu de range pour fournir augmentation infinie:

import itertools 

def _column_name_generator(): 
    column_names = [] 
    for x in itertools.count(): 
     if x < 26: 
      column_names.append(string.ascii_uppercase[x % 26]) 
     else: 
      column_names.append(column_names[x/26 - 1] + string.ascii_uppercase[x % 26]) 
     yield column_names[-1] 

Une meilleure solution, modifier le code original mais qui a rejeté la nécessité de une liste consommant de mémoire de column_names, serait

import itertools, string 

def _column_name_generator(): 
    for i in itertools.count(1): 
     for p in itertools.product(string.ascii_uppercase, repeat=i): 
      yield ''.join(p) 

il itérative fondamentalement sur le produit de longueur i les lettres ASCII majuscules (chaque séquence possible) quand i augmente progressivement, à partir de 1 (A, B, C).

+0

semble un peu lourd pour la génération de maintenir une liste de column_names aussi longtemps que le nombre de yeilds – f5r5e5d

+0

@ f5r5e5d c'est vrai! Que diriez-vous d'ajouter quelque chose comme 'column_names = column_names [-26:]' à la fin pour couper la liste. Pensées? – bluprince13

+0

@ bluprince13 J'ai essayé de garder le code aussi proche de l'original; Je vais poster une méthode non mémoire consommer plus tard aujourd'hui – Uriel

1

Une manière moins pythonique

Comme il ressort de votre question, d'une manière divise par 26 convertir le reste dans une lettre à chaque étape, jusqu'à ce que le retour de la division 0. Utilisez % (modulo) pour obtenir le reste, // (division de plancher) pour mettre à jour la valeur pour l'étape suivante. Cela pourrait être le code:

numberOfElements = 100 
letters = [] 
for counter in range(numberOfElements): 
    i = counter 
    newCharacter = i % 26 
    i //= 26 
    s = "" +chr(newCharacter + ord('A')) 
    while i != 0: 
     newCharacter = i % 26 
     i //= 26 
     s = chr(newCharacter + ord('A')) + s 
    letters.append(s) 
print letters 

Résultat:

[ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', ' T ',' U ',' V ',' W ',' X ',' Y ',' Z ',' BA ', ' BB ',' BC ',' BD ',' BE ',' BF ',' BG ',' BH ',' BI ',' BJ ',' BK ',' BL ', ' BM ',' BN ',' BO ',' BP ',' BQ ',' BR ' , 'BS', 'BT', 'BU', 'BV', 'BW', 'BX', 'BY', 'BZ', 'CA', 'CB', 'CC', 'CD', 'CE', 'CF', 'CG', 'CH', 'CI', 'CJ', 'CK', ​​'CL', 'CM', 'CN', 'CO', 'CP', ' CQ ',' CR ',' CS ', CT, CU, CV, CW, CX, CY, CZ, DA, DB, DC, DD, «DE» 'DF', 'DG', 'DH', 'DI', 'DJ', 'DK', 'DL', 'DM', 'DN', 'DO', 'DP', 'DQ', ' DR », 'DS', 'DT', 'dU', 'DV']

+2

Une version de Python 3 serait bien ...:) D'autres choses que vous pourriez aimer faire: le mettre dans un générateur, permettre à l'appelant de spécifier majuscules ou minuscules, permettre à l'appelant de spécifier un point de départ de la séquence. –