Кортеж Python из параллельных файлов

У меня есть два файла, которые для каждого байта, прочитанного в одном файле, что-то должно быть сделано с байтом в той же позиции в другом - говорят Xor'ed.

Я надеялся, что у меня может быть что-то вроде ниже, но пока мне не повезло:

c = 0

f1 = list(file1.read())
f2 = list(file2.read())


for (a, b) in f1, f2: # set a and b for each byte in turn in f1 and f2
    c = a ^ b

Для меня это изначально было похоже на Python, но теперь я начинаю сомневаться в этом.

Любые указатели приветствуются!


person peedurrr    schedule 13.01.2014    source источник


Ответы (1)


Используйте zip() функцию:

for a, b in zip(f1, f2):

Если файлы большие, вы, вероятно, захотите использовать более мелкие куски, а не читать весь файл в память.

Для текстовых файлов просто перебирайте файлы напрямую, чтобы получить строки:

try:
    from itertools import izip
except ImportError:  # Python 3, use builtin zip
    izip = zip

with file1, file2:
    for line1, line2 in izip(file1, file2):
        for a, b in izip(line1, line2):

где вместо этого мы используем izip() функцию (только в Python 2) чтобы предотвратить чтение в первую очередь целых файлов. Это также предполагает, что линии имеют одинаковую длину.

Для двоичных файлов читайте кусками, используя размер куска, равный степени двойки:

file1_it = iter(file1, lambda f: f.read(2048))
file2_it = iter(file2, lambda f: f.read(2048))

for chunk1, chunk2 in izip(file1_it, file2_it):
    for a, b in izip(chunk1, chunk2):
person Martijn Pieters    schedule 13.01.2014
comment
Я хотел бы добавить, что причина, по которой izip отсутствует в python 3, заключается в том, что в python 3 zip уже работает как izip. - person kazagistar; 13.01.2014
comment
@kazagistar: да, и я не хотел маскировать встроенный zip() в Python 2, поэтому я решил повторно привязать zip к izip в 3, а не наоборот, повторно привязав izip к zip в Python 2. - person Martijn Pieters; 13.01.2014