Итерация по объекту чтения CSV в Python - PullRequest
0 голосов
/ 24 апреля 2020

У меня есть два CSV-файла, один из которых, вероятно, будет содержать еще несколько записей, а другой. Я пишу функцию для итерации по каждой и определения, какие записи находятся в дампе, но не лжец.

Мой код выглядит следующим образом:

def update_lib(x, y):
    dump = open(x, newline='')
    libr = open(y, newline='')
    dump_reader = csv.reader(dump)
    for dump_row in dump_reader:
        libr_reader = csv.reader(libr)
        for libr_row in libr_reader:
            if dump_row[0] == libr_row[0]:
                break

Я ожидаю, что это займет первую строку в dump (dump_row) и итерации по каждой строке в библиотеке (libr_row), чтобы увидеть, совпадают ли первые элементы. Если они это сделают, я хочу перейти к следующему ряду в дампе, а если нет, то, в конце концов, сделаю что-нибудь еще.

Моя проблема в том, что libr_reader «запоминает», где он находится, и я не могу его получить go вернуться к первой строке в libr, даже когда достигнут break, и поэтому я ожидаю, что libr_reader будет повторно инициирован. Я даже пробовал del libr_row и del libr_reader, но, похоже, это не имеет значения. Я подозреваю, что я неправильно понимаю итераторов, любая помощь с благодарностью получена.

1 Ответ

0 голосов
/ 24 апреля 2020

Как показано в вашем вопросе, вы будете создавать libr_reader объект каждый раз, когда вы повторяете строку в dump_reader.

dump_reader = csv.reader(dump)
for dump_row in dump_reader:
    libr_reader = csv.reader(libr)

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

Согласно нашему обсуждению в комментариях, вы это знаете, но то, что вы Вы не знаете, что объект чтения работает с тем же дескриптором файла и, таким образом, все еще находится в том же курсоре.

Рассмотрите этот пример:

>>> import io
>>> my_file = io.StringIO("""Line 1
... Another Line
... Finally, a third line.""")

Это создает смоделированный Файловый объект. Теперь я создам класс «LineReader».

>>> class LineReader:
...     def __init__(self, file):
...         self.file = file
...     def show_me_a_line(self):
...         print(self.file.readline())
... 

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

>>> line_reader = LineReader(my_file)
>>> line_reader.show_me_a_line()
Line 1

>>> second_line_reader = LineReader(my_file)
>>> second_line_reader.show_me_a_line()
Another Line

>>> third_line_reader = LineReader(my_file)
>>> third_line_reader.show_me_a_line()
Finally, a third line.

Для объекта my_file нет никакой материальной разницы между тем, что я только что сделал, и выполнением этого напрямую. Во-первых, я «сброслю» файл в начало, вызвав seek (0):

>>> my_file.seek(0)
0
>>> my_file.readline()
'Line 1\n'
>>> my_file.readline()
'Another Line\n'
>>> my_file.readline()
'Finally, a third line.'

Вот оно у вас.

Итак, TL / DR: файлы имеют курсоры и запоминают где они. Думайте о дескрипторе файла как о вещи, которая запоминает, где находится файл, да, но также запоминает, где в файле находится ваша программа.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...