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

时间:2013-08-25 20:41:28

标签: python

我正在尝试在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函数调用以强制进行评估。但它似乎很奇怪(我不关心返回值,为什么我应该将迭代器转换为列表?)

有更好的解决方案吗?

6 个答案:

答案 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))