Подтвердить что ты не робот

В Python, как мне перебирать один итератор, а затем другой?

Я бы хотел повторить два разных итератора, примерно так:

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

Что я ожидал бы напечатать все строки файла1, а затем все строки файла2.

Мне нужно что-то общее, поскольку итераторы могут быть не файлами, это всего лишь пример. Я знаю, что могу сделать это с помощью:

for item in [file1]+[file2]:

но это считывает оба файла в память, которые я бы предпочел избежать.

4b9b3361

Ответ 1

Используйте itertools.chain:

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

fileinput модуль также обеспечивает аналогичную функцию:

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

Ответ 2

Вы также можете сделать это с помощью простого выражения :

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

с помощью этого метода вы можете указать некоторое условие в самом выражении:

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

Приведенный выше пример эквивалентен этому генератору с циклом:

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'

Ответ 3

Я думаю, что наиболее Pythonic подход к этой конкретной проблеме файла заключается в использовании модуля fileinput (так как вам либо нужны сложные менеджеры контекста, либо обработка ошибок с помощью open), я собираюсь начать с примера Ashwini, но добавьте несколько вещей. Во-первых, лучше открыть флажок U для поддержки Universal Newlines (при условии, что ваш Python скомпилирован с ним, и большинство из них), (r - режим по умолчанию, но явный лучше, чем неявный). Если вы работаете с другими людьми, лучше всего поддерживать их, давая вам файлы в любом формате.

import fileinput

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

Это также можно использовать в командной строке, так как он будет принимать sys.argv [1:], если вы это сделаете:

import fileinput

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

И вы передадите файлы в своей оболочке следующим образом:

$ python myscript.py file1 file2