首页 > 解决方案 > 在 Python 中同时从文件中检索 CSV 字段和原始字符串

问题描述

我有一个生成器,它一次从 CSV 文件中生成行,例如:

import csv

def as_csv(filename):
    with open(filename) as fin:
        yield from csv.reader(fin)

但是,我需要捕获从文件返回的原始字符串,因为这需要同时保留。

据我所知,csv内置可以临时使用,如下所示:

import csv

def as_csv_and_raw(filename):
    with open(filename) as fin:
        for row in fin:
            raw = row.strip()
            values = csv.reader([raw])[0]
       yield (values, raw)

...但这有为文件的每一行创建一个新的读取器和一个新的迭代器的开销,所以对于具有数百万行的文件,我担心性能影响。

感觉就像我可以创建一个可以与主函数交互的协程,以一种我可以直接控制输入而不会丢失它的方式产生解析的字段,如下所示:

import csv

def as_csv_and_raw(filename):
    with open(filename) as fin:
        reader = raw_to_csv(some_coroutine())
        reader.next()
        for row in fin:
            raw = row.strip()
            fields = reader.send(raw)
            yield fields, raw

def raw_to_csv(data):
    yield from csv.reader(data)

def some_coroutine():
    # what goes here?
    raise NotImplementedError

我还没有真正把头放在协程上并yield用作表达式,所以我不确定里面是什么some_coroutine,但目的是每次我输入send一个值时,该值都会通过csv.reader对象运行并且我得到集合的领域回来。

有人可以提供实现some_coroutine,或者向我展示获取所需数据的更好机制吗?

标签: pythongenerator

解决方案


您可以使用itertools.tee从可迭代文件对象创建两个独立的迭代器,csv.reader从其中一个创建一个,然后用它压缩另一个迭代器以输出:

from itertools import tee

def as_csv_and_raw(filename):
    with open(filename) as fin:
        row, raw = tee(fin)
        yield from zip(csv.reader(row), raw)

推荐阅读