仅使用 += 怎么会导致无限循环?

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

a = [-1, -2, -3]
。我想修改列表
a
以便
a == [-1, -2, -3, 1, 2, 3]
,并且我想使用
map
来实现这一点。

我编写了以下不同的代码来执行此操作:

  1. a = a + map(abs, a)
  2. a = a + list(map(abs, a))
  3. a += map(abs, a)
  4. a += list(map(abs, a))

结果如下:

  1. TypeError: can only concatenate list (not "map") to list
  2. 按预期工作:
    a = [-1, -2, -3, 1, 2, 3]
  3. 无限期挂起,然后终止且没有错误消息(可能内存不足?)
  4. 按预期工作:
    a = [-1, -2, -3, 1, 2, 3]

我认为

a += b
只是
a = a + b
的语法糖,但是,考虑到 (1) 和 (3) 的行为方式,显然情况并非如此。

为什么 (1) 会出错,而 (3) 似乎进入无限循环,尽管其中一个通常只是另一个的语法糖版本?

python addition syntactic-sugar
1个回答
0
投票

如示例所示,

a += b
不等于
a = a + b
,并且这个答案解释了原因

在底层,

a += b
调用
__iadd__
,当
a
是一个列表时,它会迭代
b
,将
b
的每个元素添加到
a
。然而,
a = a + b
将在(第二个)
__add__
上调用
a
,它将尝试将
b
基本上一次性连接到(第二个)
a
,但该方法将检测到
b
不是
list
并且失败。

a += b
情况会导致无限循环,因为
map
在迭代时一次仅计算并生成一个元素。因此,它将返回第一个数字
abs(-1) == 1
,该数字将被附加到
a
所以
a == [-1, -2, -3, 1]
。然后,在附加之后,将要求返回第二个数字,
abs(-2) == 2
,所以
a == [-1, -2, -3, 1, 2]
。这一直持续到
a == [-1, -2, -3, 1, 2, 3]
,然后 still 继续(因为现在
a
中的值比原来的三个值多)。因此
map
接下来将返回
abs(1) == 1
,现在
a == [-1, -2, -3, 1, 2, 3, 1]
,然后下一步,
a == [-1, -2, -3, 1, 2, 3, 1, 2]
,依此类推,直到内存耗尽。

简而言之,

+=
调用
__iadd__
+
调用
__add__
,并且它们的实现方式不同。
__iadd__
函数将在任何可以迭代的地方运行,但
__add__
执行一种类型检查以确保它连接的东西是一个列表。因此,
+=
会导致无限循环,而
+
会导致错误。

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