49 votes

En Python, comment puis-je effectuer une itération sur un itérateur et puis d'une autre?

Je tiens à itérer les deux itérateurs, quelque chose comme ceci:

file1 = open('file1', 'r')
file2 = open('file2', 'r')
for item in one_then_another(file1, file2):
    print item

Qui je m'attends à imprimer toutes les lignes de fichier1, puis toutes les lignes de fichier2.

J'aimerais quelque chose de générique, comme les itérateurs peuvent ne pas être des fichiers, c'est juste un exemple. Je sais que je pourrais le faire avec:

for item in [file1]+[file2]:

mais il lit les fichiers dans la mémoire, je préfère éviter.

89voto

Ashwini Chaudhary Points 94431

Utiliser itertools.chain:

from itertools import chain
for line in chain(file1, file2):
   pass

fileinput module fournit également une fonctionnalité similaire:

import fileinput
for line in fileinput.input(['file1', 'file2']):
   pass

17voto

ndpu Points 8679

Vous pouvez aussi le faire avec un simple générateur d'expression:

for line in (l for f in (file1, file2) for l in f):
    # do something with line

avec cette méthode, vous pouvez spécifier un état dans l'expression elle-même:

for line in (l for f in (file1, file2) for l in f if 'text' in l):
    # do something with line which contains 'text'

L'exemple ci-dessus est équivalent à ce générateur et de la boucle:

def genlinewithtext(*files):
    for file in files:
        for line in file:
            if 'text' in line:
                yield line

for line in genlinewithtext(file1, file2):
    # do something with line which contains 'text'

7voto

Aaron Hall Points 7381

Je pense que le plus Pythonic approche à ce problème de fichier est d'utiliser l' fileinput module (depuis, vous avez besoin du contexte complexe de gestionnaires ou d'erreur de manipulation avec open- )), je vais commencer avec Ashwini l'exemple, mais ajouter un peu de choses. La première est qu'il est préférable de l'ouvrir avec l' U indicateur Universel des retours à la ligne de support (en supposant que votre Python est compilé avec elle, et la plupart le sont), (r est par défaut, mais explicite est mieux que de manière implicite). Si vous travaillez avec d'autres personnes, il est préférable de les soutenir, de vous donner les fichiers dans n'importe quel format.

import fileinput

for line in fileinput.input(['file1', 'file2'], mode='Ur'):
   pass

C'est également utilisable sur la ligne de commande, car il faudra sys.argv[1:] si vous faites cela:

import fileinput

for line in fileinput.input(mode='Ur'):
   pass

Et vous voulez passer les fichiers dans votre interpréteur de commandes comme ceci:

$ python myscript.py file1 file2

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X