Python - CSV读取器列表推导式

4

我正在尝试使用CSV reader高效地读取文件中的列。代码如下:

import csv
csv.register_dialect('csvrd', delimiter='\t', quoting=csv.QUOTE_NONE)


with open('myfile.txt', 'rb') as f:
    reader = csv.reader(f,'csvrd')
    a0=[x[0] for x in reader]
    a1=[x[1] for x in reader]

我获取了第一列的数值,但a1为空。如果我先写a1,那么a0就为空。

我知道一个简单的解决方案,插入

reader=[x for x in reader]

但是我很好奇这个原因。当你从读者那里阅读一个条目时,它会被删除吗?

一个样本myfile.txt

c11 c21 c31
c21 c22 c32

[x for x in reader] 可以写成 list(reader)。然而,显式的 for 循环可能更好:您可以精确地遍历 CSV 文件一次,并在代码尝试两次时执行任何操作而不会出现任何问题。虽然可以在列表推导中编写相同的内容,但是推导并不总是更清晰/Pythonic。 - x3al
2个回答

8

如果不重新将底层文件定位到开头,就不能多次循环reader

但是,请勿这样做;而是使用zip(*reader)将行转置为列:

a0, a1, a2 = zip(*reader)

演示:

>>> import csv
>>> csv.register_dialect('csvrd', delimiter='\t', quoting=csv.QUOTE_NONE)
>>> data = '''\
... c11\tc21\tc31
... c21\tc22\tc32
... '''
>>> reader = csv.reader(data.splitlines(True), 'csvrd')
>>> a0, a1, a2 = zip(*reader)
>>> a0
('c11', 'c21')
>>> a1
('c21', 'c22')
>>> a2
('c31', 'c32')

2

csv.reader 返回一个生成器。如果要再次从生成器中读取数据,您需要重新声明它。这个答案详细解释了Python生成器的工作原理。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接