为什么这个Python代码(使用自己的地图合成列表扩展)会使我的系统冻结?

Mar*_*son 5 python lambda freeze

我跑的时候

a = ['a']
a.extend(map(lambda x: 'b' + x, a))
Run Code Online (Sandbox Code Playgroud)

它将我的系统锁定,直到我可以执行Ctrl + C,如果我从shell运行它作为Python脚本,并从解释器运行它让我必须硬关闭我的笔记本电脑.

然而,

a = ['a']
a.extend(list(map(lambda x: 'b' + x, a)))
Run Code Online (Sandbox Code Playgroud)

工作正常并给出预期的结果.

为什么会这样?

起初,我认为这可能是因为我试图a用自己运行的map函数进行扩展a,所以我写道:

a = ['a']
tmp = map(lambda x: 'b' + x, a)
a.extend(tmp)
Run Code Online (Sandbox Code Playgroud)

然而,这也冻结了.

同样,这似乎工作正常:

a = ['a']
tmp = list(map(lambda x: 'b' + x, a))
a.extend(tmp)
Run Code Online (Sandbox Code Playgroud)

为什么会这样?

我在Python 3.4.3上这样做.

小智 1

在 python 3 中,迭代器将从map()函数生成。

当看到a.extend()函数时,python会发现你想用a与之相关的迭代器来扩展列表a,并自动帮助你进行迭代。

迭代从这里开始。

首先,它是'a'a中的。函数内部的迭代器map()给出'a', a'ba'是从lambda表达式生成的并附加到 list 中aa变成['a', 'ba']现在。

然后,map()函数内部的迭代器发现由于新朋友的到来,迭代a没有给出。所以函数内部的迭代器给出了for来处理。A在这里生成并被推入。StopIterationa'ba'map()'ba'lambda'bba'a

这就是a无限传播的原理。

以下代码可能会有所帮助:

a = ['a']
import time
a.extend(map(lambda x: ('b' + x, print(x), time.sleep(1))[0], a))
Run Code Online (Sandbox Code Playgroud)

list()理解为什么使用将迭代器转换为静态列表不会触发此问题应该很简单。