2014-02-17 5 views
48

Ich möchte zwei verschiedene Iteratoren iterieren, etwa wie folgt:Wie kann ich in Python einen Iterator durchlaufen und dann einen anderen?

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

Was ich erwarten würde alle Linien der file1 zu drucken, dann alle Linien der file2.

Ich möchte etwas generisches, da die Iteratoren möglicherweise keine Dateien sind, dies ist nur ein Beispiel. Ich weiß, dass ich dies tun könnte mit:

aber dies liest beide Dateien in den Speicher, die ich lieber vermeiden würde.

+2

Für zukünftige Leser ist die beste allgemeine Antwort, wie in dieser Frage gefordert, itertools.chain, wie Ashwini hier sagt. –

+0

Wenn Sie mit Dateien arbeiten, ist ** 'fileinput' ** die einzig wahre Lösung. – laike9m

Antwort

88

Verwendung itertools.chain:

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

fileinput Modul bietet auch eine ähnliche Funktion:

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

Sie auch können es mit einfachen generator expression:

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

mit diesem mir thod können Sie einige Bedingung in Ausdruck angeben selbst:

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

Das obige Beispiel ist äquivalent zu diesem Generator mit Schleife:

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' 
7

Ich denke, die meisten Pythonic Ansatz für diese bestimmte Datei Problem Verwenden Sie das fileinput Modul (da Sie entweder komplexe Kontextmanager oder Fehlerbehandlung mit open benötigen), ich werde mit Ashwini Beispiel beginnen, aber ein paar Dinge hinzufügen. Der erste ist, dass es besser ist, mit dem U Flag für Universal Newlines Unterstützung zu öffnen (vorausgesetzt, Ihr Python ist damit kompiliert, und die meisten sind), (r ist Standardmodus, aber explizit ist besser als implizit). Wenn Sie mit anderen Personen arbeiten, ist es am besten, sie dabei zu unterstützen, Dateien in einem beliebigen Format zu erstellen.

import fileinput 

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

Dies ist auf der Kommandozeile auch verwendbar, da es sys.argv nehmen [1:], wenn Sie dies tun:

import fileinput 

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

Und Sie würden die Dateien in der Shell wie folgt passieren:

$ python myscript.py file1 file2 
+0

Können Sie den Moduswert auf 'rU' korrigieren? Als ich den Code mit 'Ur' ausprobierte, beschwerte sich der Interpreter so: "ValueError: FileInput Öffnungsmodus muss einer von 'r', 'rU', 'U' und 'rb' sein." – kmario23

Verwandte Themen