我有一个csv DictReader对象(使用Python3.1),但是在遍历它之前,我想知道阅读器中包含的行数/行数。类似于下面的内容。
myreader = csv.DictReader(open('myFile.csv', newline=''))
totalrows = ?
rowcount = 0
for row in myreader:
rowcount +=1
print("Row %d/%d" % (rowcount,totalrows))
我知道我可以通过遍历阅读器得到总数,但是我不能运行'for‘循环。我可以遍历阅读器的副本,但我找不到如何复制迭代器。
我也可以使用
totalrows = len(open('myFile.csv').readlines())
但这似乎是不必要的重新打开文件。如果可能的话,我更愿意从DictReader获取计数。
任何帮助都将不胜感激。
艾伦
发布于 2010-05-23 11:13:08
rows = list(myreader)
totalrows = len(rows)
for i, row in enumerate(rows):
print("Row %d/%d" % (i+1, totalrows))
发布于 2010-05-23 16:17:32
您只需打开该文件一次:
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
无论您做什么,您都必须进行两次遍历(如果您的记录是固定长度的-这是不太可能的-您可以只获得文件大小并进行划分,但假设情况并非如此)。再次打开该文件确实不会花费您太多成本,但您可以避免这样做,如下所示。仅仅为了使用len()
而转换为列表可能会浪费大量内存,而且速度也不会更快。
注意:“Pythonic”的方法是使用enumerate
而不是+=
,但是UNPACK_TUPLE
操作码的开销太大,使得enumerate
比递增local更慢。话虽如此,这可能是一个不必要的微优化,您可能应该避免。
更多注释:如果你真的只想生成某种进度指示器,它不一定是基于记录的。您可以在循环中对文件对象执行tell()
操作,并且只报告您正在处理的数据的百分比。这可能会有点不均匀,但任何足够大的文件都有可能需要一个进度条,记录长度的偏差将在噪音中消失。
发布于 2010-05-23 13:25:31
我找不到如何复制迭代器。
Closest是itertools.tee,但就像@J.F.Sebastian建议的那样,简单地对其进行list
是最好的,正如itertools.tee的文档所解释的那样:
此itertool可能需要大量的辅助存储(取决于需要存储多少临时数据)。通常,如果一个迭代器在另一个迭代器启动之前使用了大部分或所有数据,则使用
list()
而不是tee()
会更快。
https://stackoverflow.com/questions/2890549
复制相似问题