Python3中非地图评估版的地图?

yeg*_*gle 19 python

我正在尝试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)


daw*_*awg 5

您可以设置零长度的双端队列来做到这一点:

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。


don*_*lan 5

list(map(lambda x: do(x),y))\n
Run Code Online (Sandbox Code Playgroud)\n

将触发评估并保留英语纸笔数学语义。有些人比其他人更喜欢这个,但我有一个以英语为第二语言的程序员告诉我,这比以下更难理解:

\n
[ do(x) for x in y ]\n
Run Code Online (Sandbox Code Playgroud)\n

\xc2\xaf\\ (\xe3\x83\x84) /\xc2\xaf

\n

无论如何,如果您想刷新map堆栈,请通过list类型转换或列表理解来触发它。

\n
\n

结合上下文:

\n
import 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 ]\n
Run Code Online (Sandbox Code Playgroud)\n