请考虑以下示例代码。给出该示例只是为了突出显示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.imap
在 Python 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.
这是正确的方法,还是有更好的方法?
提前谢谢。
itertools
函数返回生成器;它们仅在迭代时运行。 因此,在您运行它完成之前,itertools.imap(f, range(3))
实际上不会做任何事情,例如使用 list
.
根据 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)
您不正确地使用了map()
。 它不应该用于函数调用的副作用,而应该用于转换可迭代对象。
您可以使用list(itertools.imap(f, range(3)))
来获得所需的行为,但我认为您应该更改整个方法以使用法线 for 循环:
for i in range(3):
f(i)
这清楚地表明未使用f()
调用的返回值。
不同之处在于 Python 2.x 中的 map
相当于 Python 3 中的list(map(...))
。就是这样 - 没什么特别的...