csv.writer.writerows需要迭代器吗?

iru*_*var 5 python csv

该文档writerows状态

将所有行参数(如上所述的行对象列表)写入编写者的文件对象,并根据当前方言格式化。

它建议writerows以列表作为参数。但这可能需要迭代器,没问题

python -c 'import csv
> csv.writer(open("test.file.1", "w")).writerows(([x] for x in xrange(10)))
> '
cat test.file.1
0
1
2
3
4
5
6
7
8
9
Run Code Online (Sandbox Code Playgroud)

是什么赋予了?是否在将迭代器写到文件之前将迭代器转换为列表,还是文档引起误解,并且实际上可以将迭代器写入文件而无需实现它们?基础代码在C;我说不通

Bak*_*riu 3

根据该类的来源csvDictWriter首先创建一个行列表以传递给实际的编写者。参见第155 行

def writerows(self, rowdicts):
    rows = []
    for rowdict in rowdicts:
        rows.append(self._dict_to_list(rowdict))
    return self.writer.writerows(rows)
Run Code Online (Sandbox Code Playgroud)

有趣的是,在模块(C 扩展)Writer中实现的类不需要列表。我们可以从源代码中看到它只是从参数中获取一个可迭代对象并调用:_csvPyIter_Next

csv_writerows(WriterObj *self, PyObject *seqseq)
{
    PyObject *row_iter, *row_obj, *result;

    row_iter = PyObject_GetIter(seqseq);
    // [...]
    while ((row_obj = PyIter_Next(row_iter))) {
        result = csv_writerow(self, row_obj);
        // [...]
}
Run Code Online (Sandbox Code Playgroud)

请注意,根本没有对PyList_*方法的调用,也没有对类型的任何检查list

在任何情况下,这两种 writerows方法都接受任何可迭代对象,但是DictWriter将创建一个(不必要的)中间列表。在以前的版本中,该类可能Writer只接受lists,因此DictWriter必须进行该转换,但现在它已经过时了。

在当前版本的 python 中,该DictWriter.writerows方法可以重新实现为:

def writerows(self, rowdicts):
    return self.writer.writerows(map(self._dict_to_list, rowdicts))
    # or:
    #return self.writer.writerows(self._dict_to_list(row) for row in rowdicts)
Run Code Online (Sandbox Code Playgroud)

除了避免不必要地创建行列表之外,它应该具有相同的行为。