我有一个简单的问题:
如果我有一个功能:
a = [1,2,3,4,5,6,7]
def f(x):
return (x**2)
result = list(map(f, a))
print(result)
>>> [1, 4, 9, 16, 25, 36, 49]
但如果我:
result = []
a = [1,2,3,4,5,6,7]
def f(x):
result.append(x**2)
map(f, a)
print(result)
>>> []
它不会工作。
但是,如果我以这种方式编写函数,它将起作用:
result = []
a = [1,2,3,4,5,6,7]
def f(x):
result.append(x**2)
for i in a:
f(i)
print(result)
>>> [1, 4, 9, 16, 25, 36, 49]
即使我为其包含一个返回值:
result = []
a = [1,2,3,4,5,6,7]
def f(x):
result.append(x**2)
return x**2
map(f, a)
print(result) # >>> []
print(list(map(f,a))) # >>> [1,2,3,4,5,6,7]
我应该理解它,因为map()必须应用于具有返回值且仅返回值的函数。
答案 0 :(得分:9)
您在这里看到的是lazy-evaluation的效果。 Python 3使大多数这样的函数(map
,filter
,zip
等)懒得工作,他们曾经在Python 2中热切地工作,也就是说,而不是立即返回并实现数据-structure当你调用map(f, some_iterable)
时,map
会返回一个map-object,然后可以将其迭代到实现数据结构或逐个使用元素(让你工作)以记忆效率的方式)。
>>> result = []
>>> m = map(lambda x: result.append(x), range(10))
>>> m
<map object at 0x10a0b7278>
>>> result
[]
>>> next(m)
>>> result
[0]
>>> next(m)
>>> result
[0, 1]
>>> list(m)
[None, None, None, None, None, None, None, None]
>>> result
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
你应该不使用map
或filter
或列表推导来解决他们的副作用。这些都是功能结构,你应该避免在使用时改变状态。这只是糟糕的风格,而且,正如你在我的地图对象上调用list
时所注意到的那样,它会创建并立即丢弃一个无用的None
列表(因为这些函数不会返回任何内容)隐含地返回None
)。
所以,回答你的问题,是的,你可以使用&#34; map()来表示不返回值的函数&#34;但你不应该。只需使用for循环。
答案 1 :(得分:3)
map
创建一个迭代器。它不会立即执行映射,它会在您使用迭代器时逐个执行它。 list(map(...))
会立即使用整个迭代器将其转换为列表。但是在你的测试中它不起作用,你永远不会使用迭代器,所以f
永远不会被调用一次。
换句话说:不起作用:
map(f, a)
print(result)
使用:
list(map(f, a)) # ← list consumes the iterator
print(result)
答案 2 :(得分:0)
使用 Python 2 它将有效...
我尝试了所有这些,这是我的结果集:
[1, 4, 9, 16, 25, 36, 49]
[1, 4, 9, 16, 25, 36, 49]
[1, 4, 9, 16, 25, 36, 49]
[1, 4, 9, 16, 25, 36, 49]
[1, 4, 9, 16, 25, 36, 49]