Подтвердить что ты не робот

Является ли поведение списка Python + = iterable документированным в любом месте?

Похоже, что в 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. Это описано в документации.

4b9b3361

Ответ 1

Из Гвидо ван Россум:

Он работает так же, как .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

Ответ 2

Нет (Guido подтверждает, благодаря Ashwini Chaudhary). Поведение += для последовательностей в целом недоказано. Я пришел к выводу, что спецификацией не требуется, чтобы x + y, где x - список, а y некоторая другая итерабельная ошибка (так что другие реализации могли ее разрешить), и что другие реализации могут ограничивать += для получения однородных операндов.

Однако причины не делать этого очевидны: python вообще пытается делать правильные вещи с операндами, вместо того, чтобы требовать жесткого равенства типов. Настоящая загадка заключается в том, почему гетерогенное добавление не разрешено списками.

Обновление: я никогда не думал о проблеме неоднородного сложения, в основном потому, что itertools.chain является в значительной степени полным решением проблемы.

Комментарии от тех, кто больше знаком с внутренними компонентами Python, могут объяснить, почему добавление должно быть однородным. (Вопрос здесь: Почему добавление списка Python должно быть однородным?)

Ответ 3

Теперь теперь документировано в Python 3.4+ и Python 2.7:

4.6.3. Типы изменяемой последовательности

Операции в следующей таблице определены в изменяемых типах последовательностей. collections.abc.MutableSequence ABC предоставляется, чтобы упростить правильное выполнение этих операций над пользовательскими типами последовательностей.

[Ниже] s - это экземпляр типа изменяемой последовательности, t - любой итерируемый объект, а x - произвольный объект, который соответствует любым ограничениям типа и значения, налагаемым s (например, bytearray принимает только целые числа, которые соответствуют ограничению значения 0 <= x <= 255).


s.extend(t) или s += t

extends s с содержимым t (по большей части такое же, как s[len(s):len(s)] = t)

Итак, теперь задокументировано, что для любого изменяемого типа последовательности s, s += t является синонимом s.extend(t).