在多张地图上的迭代

问题描述 投票:0回答:2

我有一个关于Python(3)在计算多个地图时如何在内部循环的问题。这是个废话的例子:

from random import randint

A = [randint(0,20) for _ in range(100)]
map1 = map(lambda a: a+1, A)
map2 = map(lambda a: a-1, map1)
B = list(map2)

因为map()产生了一个惰性表达式,在调用list(map2)之前,实际上没有任何计算,对吗?

[终于完成计算时,更类似于以下哪种方法?

循环方法1:

A = [randint(0,20) for _ in range(100)]
temp1 = []
for a in A:
    temp1.append(a+1)

B = []
for t in temp1:
    B.append(t-1)

循环方法2:

A = [randint(0,20) for _ in range(100)]
B = []
for a in A:
    temp = a+1
    B.append(temp-1)

还是以完全不同的方式进行计算?

python lazy-evaluation
2个回答
1
投票

[通常,map()函数会生成一个生成器,该生成器反过来不会生成任何输出或计算任何内容,除非明确要求。将生成器转换为列表本质上类似于向其询问下一个元素,直到没有下一个元素为止。

我们可以在命令行上做一些实验,以了解更多信息:

>>> B = [i for i in range(5)]
>>> map2 = map(lambda b:2*b, B)
>>> B[2] = 50
>>> list(map2)
[0, 2, 100, 6, 8]

我们可以看到,即使我们修改B after创建了生成器,我们的更改仍然反映在生成器的输出中。因此,似乎map保留了对原始可迭代对象的引用,并且仅在被要求时才一次计算一个值。


在您的示例中,这意味着该过程将如下所示:

A = [2, 4, 6, 8, 10]
b = list(map2)
    b[0] --> next(map2) = (lambda a: a-1)(next(map1))
             --> next(map1) = (lambda a: a+1)(next(A)) 
                 --> next(A) = A[0] = 2
             --> next(map1) = 2+1 = 3
         --> next(map2) = 3-1 = 2
    ...

用人的话来说,map2的下一个值是通过询问map1的下一个值来计算的。反过来,That

是根据最初设置的A计算的。

0
投票

这可以通过对带有副作用的函数使用map进行研究。一般来说,您不应为真正的代码执行此操作,但对于调查行为是很好的。

© www.soinside.com 2019 - 2024. All rights reserved.