我在范围内时遇到了IndexError错误

3

我正在尝试读取csv文件的行。我的文件看起来像这样:

Col 1, Col 2, Col3
row11, row12, row13
row21, row22, row23
row31, row32, row33
...

我使用以下命令来读取行:
with open('~/data.csv') as f:
    r = csv.DictReader(f)
    for i in range(5):
        print(list(r)[i])

输出打印了第一行,但接着就出现了索引错误。
IndexError                                Traceback (most recent call last)
<ipython-input-15-efcc4f8c760d> in <module>()
      2     r = csv.DictReader(f)
      3     for i in range(5):
----> 4         print(list(r)[i])

IndexError: list index out of range

我猜我在某个地方犯了一个愚蠢的错误,但是找不出来。有没有想法关于我做错了什么以及如何修复它?
编辑:这是print(list(r))的输出:
[{'Col 1': 'row11', ' Col3': ' row13', ' Col 2': ' row12'}, {'Col 1': 'row21', ' Col3': ' row23', ' Col 2': ' row22'}, {'Col 1': 'row31', ' Col3': ' row33', ' Col 2': ' row32'}, {'Col 1': 'row41', ' Col3': ' row43', ' Col 2': ' row42'}, {'Col 1': 'row51', ' Col3': ' row53', ' Col 2': ' row52'}, {'Col 1': 'row61', ' Col3': ' row63', ' Col 2': ' row62'}, {'Col 1': 'row71', ' Col3': ' row73', ' Col 2': ' row72'}, {'Col 1': 'row81', ' Col3': ' row83', ' Col 2': ' row82'}, {'Col 1': 'row91', ' Col3': ' row93', ' Col 2': ' row92'}, {'Col 1': 'row101', ' Col3': ' row103', ' Col 2': ' row102'}]

print(list(r))看起来是什么样子? - akxlr
1个回答

5

DictReader(f) 只会让你一次性查看文件 - 你只能在它上面调用一次list,但因为它在循环内,所以你可以调用多次。后续的调用会返回一个空的list。只需在循环外部调用list并将其保存在变量中,你就可以了。

也就是说:

r = csv.DictReader(f)
rows = list(r)
for i in range(5):
    print(rows[i])

或者,在任何时候都不要将整个内容全部加载到内存中:
for row in csv.DictReader(f):
    print row

如果您想将索引保留用于其他目的:
 for i, row in enumerate(csv.DictReader(f)):
     print i, row

如果你想从一个iterator(其中csv.DictReader是一种特殊情况)中获取特定的行,而不是将整个内容都读入内存,请查看https://docs.python.org/3/library/itertools.html上的itertools.islice。它基本上允许在iterator上进行类似于list的切片操作。

  # prints first five rows
  for row in itertools.islice(csv.DictReader(f), 5):
       print row

对于更为零散的行:

  needed_row_indices = {2, 5, 20}
  for i, row in enumerate(csv.DictReader(f)):
      if i in needed_row_indices:
          print row

非常感谢,虽然这对于一个小例子有效,但我的问题是我正在处理一个大约10GB的大数据集。有什么办法可以避免加载整个数据集吗? - Keivan
1
更新以展示如何避免将整个内容拉入内存。@Keivan - jwilner
1
@Keivan 请查看“itertools”,我在帖子中进行了一些解释。 - jwilner
1
@Keivan,如果你需要的行更加零散分布,我建议你a)建立一个所需行的集合--例如,needed_rows = {2, 5, 20}--然后b)使用上面的示例与enumerate,但仅在i in needed_rows时操作该行。 - jwilner
我的意思是,如果有一个公式或其他函数可以作为测试,当然可以使用它来代替集合成员关系--但如果基本上是一组硬编码的随机分布的行,不确定你能做到多好。 - jwilner
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接