csv.DictReader中的行数

Ala*_*eid 27 python iterator python-3.x

我有一个csv DictReader对象(使用Python 3.1),但我想知道在迭代它之前阅读器中包含的行数/行数.如下......

myreader = csv.DictReader(open('myFile.csv', newline=''))

totalrows = ?

rowcount = 0
for row in myreader:
    rowcount +=1
    print("Row %d/%d" % (rowcount,totalrows))
Run Code Online (Sandbox Code Playgroud)

我知道我可以通过迭代读取器来获得总数,但是我无法运行'for'循环.我可以遍历阅读器的副本,但我找不到如何复制迭代器.

我也可以用

totalrows = len(open('myFile.csv').readlines())
Run Code Online (Sandbox Code Playgroud)

但这似乎是不必要的重新打开文件.如果可能的话,我宁愿从DictReader获取计数.

任何帮助,将不胜感激.

艾伦

jfs*_*jfs 35

rows = list(myreader)
totalrows = len(rows)
for i, row in enumerate(rows):
    print("Row %d/%d" % (i+1, totalrows))
Run Code Online (Sandbox Code Playgroud)

  • 请注意您的数据集大小.把你的读者变成一个列表可能需要GOBS记忆. (13认同)
  • 这会将所有数据加载到内存中,计数行 -1 是非常好的解决方案 (2认同)

Nic*_*tin 15

您只需要打开一次文件:

import csv

f = open('myFile.csv', 'rb')

countrdr = csv.DictReader(f)
totalrows = 0
for row in countrdr:
  totalrows += 1

f.seek(0)  # You may not have to do this, I didn't check to see if DictReader did

myreader = csv.DictReader(f)
for row in myreader:
  do_work
Run Code Online (Sandbox Code Playgroud)

无论你做什么,你必须做两次通过(好吧,如果你的记录是一个固定的长度 - 这是不可能的 - 你可以得到文件大小和分割,但我们假设不是这种情况).再次打开文件确实不会花费太多,但您可以避免它,如此处所示.转换为仅使用的列表len()可能会浪费大量内存,而不是更快.

注意:'Pythonic'方式是使用enumerate而不是+=,但UNPACK_TUPLE操作码是如此昂贵,以至于它enumerate比递增本地更慢.话虽这么说,你可能应该避免不必要的微观优化.

更多注意事项:如果您真的只想生成某种进度指示器,则不一定必须基于记录.您可以tell()在循环中的文件对象上,只报告您通过的数据百分比.它会有点不平衡,但是任何大到足以保证进度条的文件都有可能在记录长度上的偏差将在噪声中丢失.