Skip to main content
 首页 » 编程设计

python之重置 csv.DictReader(StringIO.StringIO(some_string))

2025年05月04日19xing901022

我正在使用 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.DictReader.next() 的定义中看到这一点和 Reader_iternext() 在 _csv.c .因此,您最好按照评论中的建议将行存储在自己的某个地方。