【问题标题】:Reading .csv in Python without looping through the whole file?在 Python 中读取 .csv 而不遍历整个文件?
【发布时间】:2011-03-07 09:49:36
【问题描述】:

我看到 Python 的 csv.reader 使用的唯一方法是在 for 循环中,它遍历整个文件而不保存变量中读取的过去值。我一次只需要处理 2 行(巨大的)文件。使用 csv.reader for 循环,我一次只有 1 行。

有没有一种方法可以使用 Python 的 csv 模块只读取 csv 文件的一行,而不必将文件读取到最后?

我需要将变量设置为第一行的值,将第二组变量设置为下一行的值,同时使用两组变量进行计算,然后用第二组变量覆盖第一组变量设置,并读取新行以覆盖第二组。

【问题讨论】:

  • 可以不存储第一组吗?
  • 我不明白这个问题。您是在问我是否能够将第一行存储到变量中?
  • 是的,是什么阻止您在第二行到达之前存储第一行,然后同时使用两者?
  • 我需要为在每行数据中提供的位置之间移动的对象制作动画。我希望有一个 while 循环,它需要线来更新速度,而不是文件读取 for 循环,它会运行一个较小的 while 循环数千次。

标签: python csv iterator next


【解决方案1】:

没有什么强迫您循环使用阅读器。先读第一行,再读第二行。

import csv
rdr = csv.reader(open("data.csv"))
line1 = rdr.next() # in Python 2, or next(rdr) in Python 3
line2 = rdr.next()

【讨论】:

  • 非常有帮助,谢谢。我将行划分为列的方式是: r = csv.reader(open("data.csv")) for col1, col2, col3 in r: x = float( col1 ) y = etc... 如何我需要使用 r.next() 而不是 for 循环来调整该方法吗?换句话说,如何从整行中提取列条目?
  • @mary:在我的例子中,line1 只是一个列表,所以 line1[0] 是第一列,line1[1] 是第二列,依此类推。如果你愿意,你可以做类似的事情(col1, col2, col3)=line1
  • 在 Python 3 中,使用 next(r) 内置函数而不是 r.next() 方法。
  • @smci:你可能想解释一下为什么这样更好。
  • @BryanOakley: 因为.next() 方法在 Python3 中的迭代器上不存在 :)
【解决方案2】:

如果您总是查看正好两个连续的行,我觉得您可能会从使用成对的 recipe 中受益。来自itertools 模块:

from itertools import tee, izip
def pairwise(iterable):
   "s -> (s0,s1), (s1,s2), (s2, s3), ..."
   a, b = tee(iterable)
   next(b, None)
   return izip(a, b)

你可以这样使用:

for first_dict, second_dict in pairwise(csv.DictReader(stream)):
    # do stuff with first_dict and second_dict

【讨论】:

    【解决方案3】:

    读取 CSV:

    readCSV = csv.reader(csvFile, delimiter=',')
    

    阅读 Python 2.7 中的下一行:

        row = readCSV.next()
    

    阅读 Python 3.4 中的下一行:

        row = readCSV.__next__()
    

    【讨论】:

    • 我推荐使用row = next(readCSV)。这在 python 2.7 和 3 中都有效,除了调用你描述的方法之外什么都不做。
    【解决方案4】:

    显而易见的答案似乎是在每次迭代时只存储前一行。

    >>> for x in csv.DictReader(stream):
    ...   print prevLine
    ...   print x
    ...   prevLine = x
    ....
    

    【讨论】:

    • @TK:此代码原样会失败,因为您没有初始化 prevLine。
    【解决方案5】:

    公然窃取 TK... ...剩下的主要问题是,OP 想对文件的第一行和最后一行做什么?

    prevLine = None
    
    for x in csv.DictReader(stream):
       if prevLine is not None:
           DoWork(prevLine, x)
       else:
           Initialize(x)
       prevLine = x
    
    Finalize(prevLine)
    

    【讨论】:

    • 每一行都包含位置,然后我需要计算它们之间的速度并为从一个到下一个移动的对象设置动画。一旦最后一个位置被物体击中,程序就结束了。
    • 该问题的答案应该会告诉您接下来需要对数据做什么。要么你特别对待第一行和最后一行(就像我所做的那样),要么你需要以某种方式处理末尾的“空”上一行或下一行。
    猜你喜欢
    • 1970-01-01
    • 2013-04-23
    • 1970-01-01
    • 2022-08-18
    • 1970-01-01
    • 1970-01-01
    • 2019-09-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多