4

考虑以下示例代码。给出这个例子只是为了强调 和 之间的不同map功能itertools.imap。我真正想做的事情不能用列表理解来完成,因为在我真正的问题中,我不是创建一个列表,而是用小数组填充一个更大的 numpy 数组。所以响应下面的代码,请不要建议:[f(x) for x in range(3)]

例子:

g = []

def f(x):
    g.append(x)

我得到的结果map和 itertools.map:

map(f, range(3)) # Results in g = [0,1,2]

itertools.imap(f, range(3)) # Does not change g

我希望g按功能进行更改map。但是,我听说它map会(或确实)表现得像 itertools.imapPython 3 中的那样。即使我使用的是 Python 2.7,我也想学习使用迭代器版本的地图的正确方法。我如何使用itertools.imap来达到与使用相同的结果map

我可以:

b = itertools.imap(f, range(3))
list(b) # This gives g = [0,1,2] if starting with an empty g.

这是正确的方法,还是有更好的方法?

提前致谢。

4

3 回答 3

11

itertools函数返回生成器;它们仅在迭代时运行。所以在你运行它完成之前itertools.imap(f, range(3))实际上不会做list任何事情,例如 with 。

根据http://docs.python.org/2/library/itertools.html#recipes,使用迭代器的最有效方法是使用零长度双端队列:

collections.deque(itertools.imap(f, range(3)), maxlen=0)

但是,如果你调用一个函数是为了它的副作用,你应该使用命令式而不是函数式语法:

for i in range(3):
    f(i)
于 2012-12-14T22:08:37.160 回答
2

您使用map()不正确。它不应用于函数调用的副作用,而应用于转换可迭代对象。

您可以使用list(itertools.imap(f, range(3)))来获得您想要的行为,但我认为您应该更改整个方法以使用正常的 for 循环:

for i in range(3):
    f(i)

这清楚地表明f()没有使用来自调用的返回值。

于 2012-12-14T22:11:55.917 回答
1

不同之处在于mapPython 2.x 中相当于list(map(...))Python 3。就是这样 - 没什么特别的......

于 2012-12-14T22:09:37.520 回答