【问题标题】:List extending strange behaviour [duplicate]列出扩展奇怪行为[重复]
【发布时间】:2023-03-03 22:13:01
【问题描述】:

在 Python (2.7) 中发现了以前从未提及的有趣事物。

这个:

a = []
a += "a"

确实有效,结果是:

>>> a
>>> ["a"]

但是

a = []
a = a + "a"

给予

>>> TypeError: can only concatenate list (not "str") to list

有人可以解释为什么吗?感谢您的回答。

【问题讨论】:

  • ++= 是不同的操作,即使它们在许多情况下看起来都一样。
  • += 的行为类似于 python 列表中的 extend()(就地添加),另一个称为二进制添加。

标签: python list


【解决方案1】:

Python 区分 ++= 运算符并为它们提供单独的钩子; __add____iadd__list() 类型只是为后者提供了不同的实现。

列表单独实现这些更有效; __add__ 必须返回一个全新的列表,而 __iadd__ 可以扩展 self 然后返回 self

在 C 代码中,__iadd__list_inplace_concat() 实现,它简单地调用 listextend(),或者在 python 代码中,[].extend()。后者按设计采用 任何 序列。

另一方面,__add__ 方法在 C 中由 list_concat 表示,它只接受 list 作为输入,可能是为了提高效率;它可以直接遍历内部 C 数组并将项目复制到新列表。

总之,__iadd__ 接受任何序列的原因是因为在实现 PEP 203(增强添加提案)时,对于列表来说,重用 .extend() 方法是最简单的。

【讨论】:

  • 谢谢,Martijn,这就是我一直在寻找的答案。
【解决方案2】:

如果a 是一个列表,则a + x 仅在x 也是列表时才有效,而a += x 适用于任何可迭代的x

以下内容可能有助于理解它:

In [4]: a = []

In [5]: a += "abc"

In [6]: a
Out[6]: ['a', 'b', 'c']

关键是"a""abc" 是可迭代的,这使得它们能够在+= 的右侧使用。

这不适用于+,因为后者要求两个操作数的类型相同(参见manual)。

要使用+ 编写相同的内容,您必须扩展可迭代对象:

In [7]: a = []

In [8]: a = a + list("abc")

In [9]: a
Out[9]: ['a', 'b', 'c']

换句话说,+= 在应用于列表时比+ 更通用。

【讨论】:

  • 问题是关于lst += iterablelst + iterable之间的区别
  • 它没有解释为什么你不能连接一个列表和一个可迭代的。
  • @MartijnPieters:当然。查看最新答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多