在 Python 中从 csv 文件的某一行进行迭代

kyr*_*nia 2 python csv python-3.x

我有一个包含数百万行的 csv 文件。我想从 10,000,000 行开始迭代。目前我有代码:

    with open(csv_file, encoding='UTF-8') as f: 
        r = csv.reader(f)
        for row_number, row in enumerate(r):    
            if row_number < 10000000:
                continue
            else:
                process_row(row)      
Run Code Online (Sandbox Code Playgroud)

这是可行的,但是需要几秒钟的时间才能出现感兴趣的行。据推测,所有不需要的行都不必要地加载到 python 中,从而减慢了速度。有没有办法在某一行上开始迭代过程 - 即不开始读入数据。

Pad*_*ham 5

您可以使用islice

from itertools import islice

with open(csv_file, encoding='UTF-8') as f:
    r = csv.reader(f)
    for row in islice(r,  10000000, None):
            process_row(row)  
Run Code Online (Sandbox Code Playgroud)

它仍然迭代所有行,但效率更高。

您还可以使用Consumer Recipe来调用以 C speed 消耗迭代器的函数,在将文件对象传递给csv.reader之前调用它,这样您也可以避免使用阅读器不必要地处理这些行:

import collections
from itertools import islice
def consume(iterator, n):
    "Advance the iterator n-steps ahead. If n is none, consume entirely."
    # Use functions that consume iterators at C speed.
    if n is None:
        # feed the entire iterator into a zero-length deque
        collections.deque(iterator, maxlen=0)
    else:
        # advance to the empty slice starting at position n
        next(islice(iterator, n, n), None)


with open(csv_file, encoding='UTF-8') as f:
    consume(f, 9999999)
    r = csv.reader(f)
    for row  in r:
          process_row(row)  
Run Code Online (Sandbox Code Playgroud)

正如 Shadowranger 评论的那样,如果一个文件可以包含嵌入的换行符,那么您将必须消耗阅读器并通过,newline=""但如果不是这种情况,则使用 do 消耗文件对象,因为性能差异将相当大,特别是如果您有很多列。