我正在尝试在Python3中使用map
。这是我正在使用的一些代码:
import csv
data = [
[1],
[2],
[3]
]
with open("output.csv", "w") as f:
writer = csv.writer(f)
map(writer.writerow, data)
但是,由于Python3中的map
返回迭代器,因此此代码在Python3中不起作用(但在Python2中工作正常,因为该map
版本始终返回list
)< / p>
我目前的解决方案是在迭代器上添加list
函数调用以强制进行评估。但它似乎很奇怪(我不关心返回值,为什么我应该将迭代器转换为列表?)
有更好的解决方案吗?
答案 0 :(得分:20)
即使在Python2.x中,如果您对返回值不感兴趣,也可以使用map
作为副作用(例如函数调用)。如果函数返回None
,但重复了一百万次 - 你将构建一个包含一百万None
的列表,只是为了丢弃它。正确的方法是使用for循环并调用:
for row in data:
writer.writerow(row)
或csv
模块允许,使用:
writer.writerows(data)
如果由于某种原因你真的,真的想要来使用map
,那么你可以使用itertools中的consume
配方并生成零长度双端队列,例如:< / p>
from collections import deque
deque(map(writer.writerow, data), maxlen=0)
答案 1 :(得分:3)
您可以设置zero length deque来执行此操作:
with open("output.csv", "w") as f:
writer = csv.writer(f)
collections.deque(map(writer.writerow, data),0)
这与itertools.consume(iterator, None)
食谱的工作方式相同。它在功能上会耗尽迭代器而不构建列表。
您也可以使用itertools
中的consume recipe。
但循环对我来说更具可读性和Pythonic,但YMMV。
答案 2 :(得分:2)
如果您不关心返回值,那么map
不是这项工作的最佳工具。一个简单的for
会更好:
for d in data:
writer.writerow(d)
这在Python 2.x和3.x中运行良好。请注意,map
在您想要创建新列表时很有用,如果您只是为了效果遍历一个iterable,那么请使用for
。
答案 3 :(得分:0)
我将使用一个函数从可迭代对象中使用类似以下的方法提取数据:
def rake(what, where=None):
for i in what:
if where: where.append(i)
rake(map(writer.writerow, data))
如果您预先知道您永远不会收集映射函数的输出,则可以将其简化为:
for i in what: pass
但是,除非您提供要放入的列表,否则这两种方法都不会保留多余的数据。而且,该方法也应与map,filter,reduce,generator,range以及您可以传递给rake函数的其他任何东西一样有效可以重复进行。
答案 4 :(得分:0)
您还可以使用列表理解as suggested in the official FAQ:
with open("output.csv", "w") as f:
writer = csv.writer(f)
[writer.writerow(elem) for elem in data]
即使您没有将新创建的列表分配给任何变量,列表理解也会强制评估每个元素。
但是请注意,该列表可能仍在幕后创建,可能会造成性能陷阱,因此虽然相对简洁,但如果输入序列过长,则不应使用该列表。
答案 5 :(得分:0)
list(map(lambda x: do(x),y))
将触发评估,并停留在美观,可读的语义中,该语义可提高人类运行时效率,而不仅仅是“ for循环(这是地图本身)加上新的段落范围转换”语义。 ¯\ (ツ) /¯
请注意,在初稿中没有理由不称其为语义糖(实际上,因为循环通常更具模块化,因此for循环通常更容易:您可能不知道在第一次尝试时代码需要做什么)问题),但是当您对处于工作状态的产品代码进行生产化或逆向工程时,提高语义效率(甚至只是用等效的好代码重写)是成功的重要因素。
无论如何,如果要刷新map
堆栈,请使用list
类型转换来触发它。
所以:
import csv
data = [
[1],
[2],
[3]
]
with open("output.csv", "w") as f:
writer = csv.writer(f)
list(map(writer.writerow, data))