我正在尝试map在Python3中使用.这是我正在使用的一些代码:
import csv
data = [
[1],
[2],
[3]
]
with open("output.csv", "w") as f:
writer = csv.writer(f)
map(writer.writerow, data)
Run Code Online (Sandbox Code Playgroud)
但是,因为map在Python3中返回一个迭代器,这段代码在Python3中不起作用(但在Python2中工作正常,因为该版本map总是返回一个list)
我目前的解决方案是list在迭代器上添加函数调用以强制进行评估.但它似乎很奇怪(我不关心返回值,为什么我应该将迭代器转换为列表?)
更好的解决方案?
Jon*_*nts 24
map当你对返回值不感兴趣时,使用它的副作用(例如函数调用)是不可取的,即使在Python2.x中也是如此.如果函数返回None,但重复了一百万次 - 你将构建一个百万Nones 的列表,只是为了丢弃它.正确的方法是使用for循环并调用:
for row in data:
writer.writerow(row)
Run Code Online (Sandbox Code Playgroud)
或者在csv模块允许的情况下,使用:
writer.writerows(data)
Run Code Online (Sandbox Code Playgroud)
如果由于某种原因你确实想要使用map,那么你可以使用consumeitertools中的配方并生成零长度双端队列,例如:
from collections import deque
deque(map(writer.writerow, data), maxlen=0)
Run Code Online (Sandbox Code Playgroud)
您可以设置零长度的双端队列来做到这一点:
with open("output.csv", "w") as f:
writer = csv.writer(f)
collections.deque(map(writer.writerow, data),0)
Run Code Online (Sandbox Code Playgroud)
这与itertools.consume(iterator, None)配方起作用的方式相同。它在功能上将耗尽迭代器而不构建列表。
您也可以只使用消耗配方从itertools。
但是对我来说,循环是更易读和Pythonic的,但是对于YMMV。
list(map(lambda x: do(x),y))\nRun Code Online (Sandbox Code Playgroud)\n将触发评估并保留英语纸笔数学语义。有些人比其他人更喜欢这个,但我有一个以英语为第二语言的程序员告诉我,这比以下更难理解:
\n[ do(x) for x in y ]\nRun Code Online (Sandbox Code Playgroud)\n\xc2\xaf\\ (\xe3\x83\x84) /\xc2\xaf
\n无论如何,如果您想刷新map堆栈,请通过list类型转换或列表理解来触发它。
结合上下文:
\nimport csv\n\ndata = [\n [1],\n [2],\n [3]\n]\n\nwith open("output.csv", "w") as f:\n writer = csv.writer(f)\n list(map(writer.writerow, data))\n # or: [ writer.writerow(x) for x in data ]\nRun Code Online (Sandbox Code Playgroud)\n