如何从python中的生成器中写入.csv文件?

时间:2022-11-11 20:21:18

My Generator looks like the following:

我的生成器如下所示:

def mygen(reader):
    for row in reader:
        yield row[0],row[1],row[2],row[3],row[4]

I'm trying to insert these generator produced values in the following manner:

我试图插入这些生成器以如下方式生成值:

file1=open(f2,"w")
writes=csv.writer(file1,delimiter=' ',quoting=csv.QUOTE_ALL)
g=mygen(reader)
for x in g:
    writes.writerow([x])

It enters blank rows to the file without producing any output. It works perfectly when I use the same generator to insert code to a table.

它向文件输入空行而不产生任何输出。当我使用相同的生成器向表中插入代码时,它可以完美地工作。

1 个解决方案

#1


9  

Your x is already a sequence, you don't need to wrap it in a list:

你的x已经是一个序列,你不需要把它打包成一个列表:

for x in g:
    writes.writerow(x)

You could just pass your generator directly to writes.writerows():

您可以直接将您的生成器传递给writer .writerows():

with open(f2, "w") as file1:
    writes = csv.writer(file1, delimiter=' ', quoting=csv.QUOTE_ALL)
    writes.writerows(mygen(reader))

Demo:

演示:

>>> import sys
>>> import csv
>>> def mygen(reader):
...     for row in reader:
...         yield row[0],row[1],row[2],row[3],row[4]
...
>>> reader = csv.reader('''\
... foo,bar,baz,spam,ham,eggs
... 42,81,13,97,73,100
... '''.splitlines())
>>> writes = csv.writer(sys.stdout, delimiter=' ', quoting=csv.QUOTE_ALL)
>>> writes.writerows(mygen(reader))
"foo" "bar" "baz" "spam" "ham"
"42" "81" "13" "97" "73"

You do need to watch out that your reader is not a generator you already exhausted. If it is a csv.reader() object, and you read all rows before, you'll need to re-wind the underlying file object back to the start with fileobj.seek(0). It'd be better to avoid reading the file twice, however.

你需要注意的是,你的读者并不是一个你已经精疲力竭的发电机。如果它是一个csv.reader()对象,并且您之前读取了所有的行,那么您将需要重新将底层文件对象以fileobject .seek(0)开头。不过,最好还是避免读两次文件。

If your reader object produces sequences (such as lists or tuples), you could just use slicing to get the first 5 elements, no need to type out every single index:

如果你的reader对象产生序列(如列表或元组),你可以使用切片来获取前5个元素,不需要输入每一个索引:

def mygen(reader):
    for row in reader:
        yield row[:5]

#1


9  

Your x is already a sequence, you don't need to wrap it in a list:

你的x已经是一个序列,你不需要把它打包成一个列表:

for x in g:
    writes.writerow(x)

You could just pass your generator directly to writes.writerows():

您可以直接将您的生成器传递给writer .writerows():

with open(f2, "w") as file1:
    writes = csv.writer(file1, delimiter=' ', quoting=csv.QUOTE_ALL)
    writes.writerows(mygen(reader))

Demo:

演示:

>>> import sys
>>> import csv
>>> def mygen(reader):
...     for row in reader:
...         yield row[0],row[1],row[2],row[3],row[4]
...
>>> reader = csv.reader('''\
... foo,bar,baz,spam,ham,eggs
... 42,81,13,97,73,100
... '''.splitlines())
>>> writes = csv.writer(sys.stdout, delimiter=' ', quoting=csv.QUOTE_ALL)
>>> writes.writerows(mygen(reader))
"foo" "bar" "baz" "spam" "ham"
"42" "81" "13" "97" "73"

You do need to watch out that your reader is not a generator you already exhausted. If it is a csv.reader() object, and you read all rows before, you'll need to re-wind the underlying file object back to the start with fileobj.seek(0). It'd be better to avoid reading the file twice, however.

你需要注意的是,你的读者并不是一个你已经精疲力竭的发电机。如果它是一个csv.reader()对象,并且您之前读取了所有的行,那么您将需要重新将底层文件对象以fileobject .seek(0)开头。不过,最好还是避免读两次文件。

If your reader object produces sequences (such as lists or tuples), you could just use slicing to get the first 5 elements, no need to type out every single index:

如果你的reader对象产生序列(如列表或元组),你可以使用切片来获取前5个元素,不需要输入每一个索引:

def mygen(reader):
    for row in reader:
        yield row[:5]