Je travaille sur un problème qui implique de valider un format à partir du correctif différent d'unified Diff.
Les variables dans le format intérieur peuvent couvrir plusieurs lignes à la fois. J'ai donc écrit un générateur qui tire chaque ligne et donne la variable Lorsqu'il est complet. p>
Pour éviter de réécrire cette fonction lors de la lecture d'un fichier DIFF unifié, j'ai créé un générateur pour désigner les caractères diff de la ligne avant de le transmettre au validateur de format interne. Cependant, je suis coincé dans une boucle infinie (à la fois dans le code et dans ma tête). J'ai résumé à un problème au code suivant. Je suis sûr qu'il y a une meilleure façon de le faire. Je ne sais tout simplement pas ce que c'est. P>
from collections import Iterable def inner_format_validator(inner_item): # Do some validation to inner items return inner_item[0] != '+' def inner_gen(iterable): for inner_item in iterable: # Operates only on inner_info type data yield inner_format_validator(inner_item) def outer_gen(iterable): class DecoratedGenerator(Iterable): def __iter__(self): return self def next(self): # Using iterable from closure for outer_item in iterable: self.outer_info = outer_item[0] inner_item = outer_item[1:] return inner_item decorated_gen = DecoratedGenerator() for inner_item in inner_gen(decorated_gen): yield inner_item, decorated_gen.outer_info if __name__ == '__main__': def wrap(string): # The point here is that I don't know what the first character will be pseudo_rand = len(string) if pseudo_rand * pseudo_rand % 2 == 0: return '+' + string else: return '-' + string inner_items = ["whatever"] * 3 # wrap screws up inner_format_validator outer_items = [wrap("whatever")] * 3 # I need to be able to # iterate over inner_items for inner_info in inner_gen(inner_items): print(inner_info) # and iterate over outer_items for outer_info, inner_info in outer_gen(outer_items): # This is an infinite loop print(outer_info) print(inner_info)
3 Réponses :
Je pense que cela fera ce que vous avez voulu dire si vous modifiez la définition de la définition de la décoratedenerator à ceci: Votre version d'origine n'a jamais terminé car son suivant () code> méthode était apatride et retournerait la même valeur chaque fois que cela s'appelait. Vous n'avez pas besoin d'avoir une méthode suivante () du tout, cependant, vous pouvez implémenter
__ iter __ () code> vous (comme je l'ai fait), puis tout fonctionne bien. P> < / p>
Je n'aime toujours pas cela beaucoup, mais au moins il est plus court et un peu plus pythonique: [modifier] inner_gen () code> et OUTER_GEN () CODE> SANS IMAP et partiel: P>
def transmogrify(iter_of_iters, *transmogrifiers):
for iters in iter_of_iters:
yield (
trans(each) if trans else each
for trans, each in izip(transmogrifiers, iters)
)
for outer, inner in transmogrify(imap(split, stuff), inner_format_validator, None):
print inner, outer
Merci pour l'exemple de Comment utiliser FuncTools.Partial code>. Les outils sont assez astucieux, mais je trouve cette solution un peu difficile à suivre. Y aurait-il des avantages de performance pour le faire de cette façon?
Un problème est l'argument déballage dans izip (* IMAP (Split, iTerble)) code> qui décompresse l'ensemble de la totalité en mémoire en mémoire. Consultez mon autre solution pour une alternative qui évite cela. Je pense que c'est assez pythonique.
Je ferais quelque chose de plus simple, comme ceci:
import random def create_item(): return random.choice(('+', '-')) + random.choice(('foo', 'bar')) random_items = (create_item() for s in xrange(10)) added_items = ((i[0], i[1:]) for i in random_items if i.startswith('+')) valid_items = ((prefix, line) for prefix, line in added_items if 'foo' in line) print list(valid_items)
Je pense que le dernier exemple est ce que je cherche.