在Python 2中,我可以执行以下操作:
import numpy as np
f = lambda x: x**2
seq = map(f, xrange(5))
seq = np.array(seq)
print seq
# prints: [ 0 1 4 9 16]
在Python 3中,它不再起作用了:
import numpy as np
f = lambda x: x**2
seq = map(f, range(5))
seq = np.array(seq)
print(seq)
# prints: <map object at 0x10341e310>
如何获取旧行为(将map
结果转换为numpy
数组)?
编辑:正如@jonrsharpe在他的回答中指出的那样,如果我先将seq
转换为列表,则可以修复此问题:
seq = np.array(list(seq))
但我宁愿避免额外拨打list
。
答案 0 :(得分:26)
除了@jonrsharpe已经指出的有效解决方案之外,还有一个替代方案是使用np.fromiter
:
>>> import numpy as np
>>> f = lambda x: x**2
>>> seq = map(f, range(5))
>>> np.fromiter(seq, dtype=np.int)
array([ 0, 1, 4, 9, 16])
答案 1 :(得分:9)
虽然您将其称为seq
,但Python 3中的map
对象不 序列(它是一个&#39} iterator ,请参阅what's new in Python 3)。 numpy.array
需要一个序列,以便可以确定len
并保留适当的内存量;它不会消耗迭代器。例如,{em> 支持大多数序列操作的range
对象,可以直接传递;
seq = np.array(range(5))
print(seq)
# prints: [0 1 2 3 4]
要恢复以前的行为,您可以明确地将map
对象转换回序列(例如列表或元组):
seq = np.array(list(seq)) # should probably change the name!
然而,正如the documentation所说:
快速修复是将
map()
包裹在list()
中,例如list(map(...))
,但更好的解决方法通常是使用列表理解(特别是当原始代码使用lambda
时)
另一种选择是:
seq = [f(x) for x in range(5)]
或只是:
seq = [x**2 for x in range(5)]
或者,实际上从一开始就使用numpy
:
import numpy as np
arr = np.arange(5)
arr **= 2
print(arr)
# prints [ 0 1 4 9 16] in 2.x and 3.x