Python 使用生成器读取分块的CSV文件

Python 使用生成器读取分块的CSV文件,python,python-3.x,csv,iterator,generator,Python,Python 3.x,Csv,Iterator,Generator,我有一个大的csv文件需要处理,它是这样做的(非常简化): 有更好的方法,但这就是我现在所拥有的。 现在,我想将处理分为几个部分,并找到一个适合我的简单解决方案: def gen_chunks(reader, chunksize=500): chunk = [] for i, line in enumerate(reader): if (i % chunksize == 0 and i > 0): yield chunk

我有一个大的csv文件需要处理,它是这样做的(非常简化):

有更好的方法,但这就是我现在所拥有的。 现在,我想将处理分为几个部分,并找到一个适合我的简单解决方案:

def gen_chunks(reader, chunksize=500):
    chunk = []
    for i, line in enumerate(reader):
        if (i % chunksize == 0 and i > 0):
            yield chunk
            del chunk[:]
        chunk.append(line)
    yield chunk
但是,我缺乏一些生成器知识来将这两段代码组合在一起。基本上我想要这样的东西:

import csv
from csv import excel

def gen_chunks(reader, chunksize=500):
    chunk = []
    for i, line in enumerate(reader):
        if (i % chunksize == 0 and i > 0):
            yield chunk
            del chunk[:]
        chunk.append(line)
    yield chunk

def _get_dialect():
    class CustomDialect(excel):
        delimiter = ','
    return CustomDialect()

class DictIter:
    def __init__(self):
        self.reader = csv.DictReader(open('test.csv'), 
                                     fieldnames=['col1', 'col2'], 
                                     dialect=_get_dialect())

    def __iter__(self):
        return self

    def __next__(self):
        for chunk in gen_chunks(self.reader):
            for item in chunk:
                yield item

items = DictIter()
for item in items:
    print(item)

这可能有点笨拙,但我希望在对当前结构进行最小更改的情况下实现拆分处理。我试图实现的是将当前实现保留为迭代器类,但每次处理一个块,并在处理完前一个块后生成下一个块。

您的解决方案看起来是一种过于复杂的方法:

import csv

with open('test.csv',newline='') as f:
    reader = csv.DictReader(f,fieldnames=['col1', 'col2'])
    for item in reader:
        print(item)
您的分块仍然一次返回一个项目。
excel
方言的默认分隔符是逗号,
excel
是默认方言

newline=''
是打开传递给
csv
读卡器或写卡器对象的文件的有文档记录的方式


如果你有真正的分块(多处理?)的理由,你应该说明这一点,如果它不起作用,你应该展示这一尝试。

我当前的代码过于复杂,因为该类还有很多其他的东西没有在这里展示以供简化,应该作为一个迭代器类。我之所以分块是因为一些csv文件非常大,而且服务器的RAM有限,所以我想分块处理文件。在文件被读取之后,会发生大量的数据过滤和转换,从而消耗资源。我试图实现的是将当前实现保留为迭代器类,但每次处理一个块,在处理完前一个块后生成下一个块。@NST读取500行并将其作为列表一次处理与一次处理一行有什么区别?一次读取500行的内存比一行要多…操作系统正在为您缓存读取的文件。这看起来像是过早的“优化”。一定要测量…@MarkTolonen我认为你的答案没有涵盖大块部分!特别是在最后一行,你在质疑问题的目的!!我觉得这不是问题的答案。@user702846不需要。对单个进程来说,分块是毫无意义的。这次行动使问题变得过于复杂。
import csv

with open('test.csv',newline='') as f:
    reader = csv.DictReader(f,fieldnames=['col1', 'col2'])
    for item in reader:
        print(item)