我正在使用 python 的 csv.DictReader 但我用这样的字符串初始化它:
dict_reader = csv.DictReader(StringIO.StringIO(some_string))
有没有办法重置 DictReader 的迭代器,以便我可以多次使用它?我宁愿不重新解析 some_string 因为它可能是一项昂贵的操作。
您可能已经知道,初始化:
dict_reader = csv.DictReader(StringIO.StringIO(some_string))
实际上并没有从StringIO.StringIO
实例中读取任何内容。仅当dict_reader
您开始从中获取行并逐行读取输入时才开始读取。换句话说,它只会读取与您要求的行数一样多的行数。这是一个例子:
#! /usr/bin/env python
import csv
try:
from StringIO import StringIO # Python 2.x
except ImportError:
from io import StringIO # Python 3.x
test_string = """name,value
foo,1
bar,2
"""
string_io = StringIO(test_string)
#
# Position is 0 i.e. the beginning of the string.
#
print("Position: {}".format(string_io.tell()))
dict_reader = csv.DictReader(string_io)
#
# Position is still 0. Nothing has been read.
#
print("Position: {}".format(string_io.tell()))
#
# Now we start reading from string_io
#
for row in dict_reader:
print(row)
#
# Position increases every time you read
# a row using dict_reader.
#
print("Position: {}".format(string_io.tell()))
这将打印:
Position: 0
Position: 0
{'name': 'foo', 'value': '1'}
Position: 17
{'name': 'bar', 'value': '2'}
Position: 23
在所有这些结束时,当前位置string_io
将指向字符串的末尾。因此,即使您可以重复使用dict_reader
,您也必须string_io
先从头开始,然后重新开始扫描。其实,在上面的代码之后,你可以做以下事情:
string_io.seek(0)
for row in dict_reader:
print(row)
print("Position: {}".format(string_io.tell()))
此for
循环将打印以下内容:
{'name': 'name', 'value': 'value'}
Position: 11
{'name': 'foo', 'value': '1'}
Position: 17
{'name': 'bar', 'value': '2'}
Position: 23
请注意,dict_reader
现在将第一行string_io
视为数据,而不是使用它来决定字段的名称。此外,dict_reader
它本身不会保留它扫描的所有行。一旦将一行传递给您,它就不再可以通过dict_reader
. 您可以从csv.py和_csv.c的定义csv.DictReader.next()
中看到这一点。因此,您最好按照评论中的建议将行存储在自己的某个地方。Reader_iternext()