首页 > 解决方案 > 在 Python 中迭代 CSV 阅读器对象

问题描述

我有两个 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_row)中获取第一行并遍历库(libr_row)中的每一行以查看第一个元素是否匹配。如果他们这样做了,那么我想移动到转储中的下一行,如果没有,我最终会做其他事情。

我的问题是 libr_reader 似乎“记住”了它的位置,我无法让它回到 libr 中的第一行,即使break已经达到,因此我希望 libr_reader 被重新启动。我什至尝试过del libr_rowdel libr_reader但这似乎没有什么不同。我怀疑我误解了迭代器,感激地收到任何帮助。

标签: pythoncsviterator

解决方案


由于它已粘贴在您的问题中,因此每次libr_reader迭代.dump_reader

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

dump_reader这里创建一次。假设有 10 行dump_reader,您将创建 10 个libr_reader实例,全部来自同一个文件句柄。

根据我们在评论中的讨论,您知道这一点,但您不知道的是 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:文件有游标并记住它们的位置。将文件句柄视为记住文件位置的东西,是的,但也记住程序在文件中的位置。


推荐阅读