Python的列表+ = iterable的行为是否记录在任何地方?

时间:2012-12-16 18:58:00

标签: python operators containers

似乎在Python中,list += x适用于任何可迭代的x

In [6]: l = []

In [7]: l += [1]

In [8]: l += (2, 3)

In [9]: l += xrange(5)

In [10]: l
Out[10]: [1, 2, 3, 0, 1, 2, 3, 4]

这种行为是否记录在任何地方?

要与list + x进行对比,后者只有在x也是list时才有效。这是在documentation

中详细说明的

4 个答案:

答案 0 :(得分:17)

来自Guido van Rossum

  

它与.extend()的工作方式相同,只是它还返回self。一世   无法找到解释此问题的文档。 : - (

以下是从listobject.c获取的相关源代码:

list_inplace_concat(PyListObject *self, PyObject *other)
{
     PyObject *result;

     result = listextend(self, other);
     if (result == NULL)
         return result;
     Py_DECREF(result);
     Py_INCREF(self);
     return (PyObject *)self;
}

我已经提出错误报告以修复文档:http://bugs.python.org/issue16701

答案 1 :(得分:4)

Python 3.4+和Python 2.7中的now documented

  

<强> 4.6.3。可变序列类型

     

下表中的操作是在可变序列类型上定义的。提供collections.abc.MutableSequence ABC是为了更容易在自定义序列类型上正确实现这些操作。

     

[下面] s是可变序列类型的实例,t是任何可迭代对象,x是满足任何类型的任意对象和s强加的值限制(例如,bytearray只接受符合值限制0 <= x <= 255)的整数。

           

s.extend(t)s += t

     

使用s的内容扩展t(大部分内容与s[len(s):len(s)] = t相同)

现在记录下来,对于任何可变序列类型ss += ts.extend(t)同义。

答案 2 :(得分:3)

否(Guido confirms;感谢Ashwini Chaudhary)。一般来说+=对序列的行为是不明确的。我得出结论,规范并不要求x + y其中x是一个列表,y其他一些可迭代的错误(因此其他实现可以选择允许它),并且其他实现可能会限制+=需要同源操作数。

但是,不这样做的原因是显而易见的:python通常会尝试使用操作数做正确的事情,而不是要求严格的类型相等。真正的谜团是为什么列表不允许异类添加。

更新:我从未真正考虑过非均匀添加问题,主要是因为itertools.chain几乎是问题的完全解决方案。

欢迎那些更熟悉Python内部人员的评论解释为什么要求加法是同质的。 (问题:Why must Python list addition be homogenous?

答案 3 :(得分:0)

对于性能异常的情况,是的,+=extend快一点:

>>> from timeit import repeat
>>> min(repeat('a.extend((1,2,3,4,5,6,7))', 'a=[]'))
0.23489440699995612
>>> min(repeat('e((1,2,3,4,5,6,7))', 'a=[]; e = a.extend'))
0.2214308570000867
>>> min(repeat('a+=(1,2,3,4,5,6,7)', 'a=[]'))
0.21909333300027356

以下是它与append的比较:

>>> min(repeat('a.append(1)', 'a=[]'))
0.062107428999297554
>>> min(repeat('p(1)', 'a=[]; p = a.append'))
0.04968810399986978
>>> min(repeat('a+=(1,)', 'a=[]'))
0.0501599309991434

(在Python 3.7 64位,Windows上测试)