Python append () и оператор + в списках, почему они дают разные результаты? - PullRequest
96 голосов
/ 07 января 2010

Почему эти две операции (append() соответственно +) дают разные результаты?

>>> c = [1, 2, 3]
>>> c
[1, 2, 3]
>>> c += c
>>> c
[1, 2, 3, 1, 2, 3]
>>> c = [1, 2, 3]
>>> c.append(c)
>>> c
[1, 2, 3, [...]]
>>> 

В последнем случае фактически существует бесконечная рекурсия. c[-1] и c одинаковы. Чем отличается операция +?

Ответы [ 7 ]

126 голосов
/ 07 января 2010

Чтобы объяснить «почему»:

Операция + добавляет элементы array к исходному массиву. Операция array.append вставляет массив (или любой объект) в конец исходного массива, что приводит к ссылке на себя в этом месте (отсюда и бесконечная рекурсия).

Разница в том, что операция + действует специфически, когда вы добавляете массив (он перегружен, как и другие, см. эту главу о последовательностях) путем объединения элемента. Однако метод append делает буквально то, что вы просите: добавьте объект с правой стороны, который вы ему даете (массив или любой другой объект), вместо того, чтобы брать его элементы.

Альтернатива

Используйте extend(), если вы хотите использовать функцию, которая действует аналогично оператору + (как и другие здесь показали). Не имеет смысла делать обратное: пытаться имитировать добавление с помощью оператора + для списков (см. Мою более раннюю ссылку о том, почему).

Маленькая история

Для забавы, небольшая история: рождение модуля массива в Python в феврале 1993 года. Это может вас удивить, но массивы были добавлены намного позже появления последовательностей и списков.

17 голосов
/ 03 июля 2013

Оператор конкатенации + - это двоичный инфиксный оператор, который при применении к спискам возвращает новый список, содержащий все элементы каждого из его двух операндов. Метод list.append() представляет собой mutator для list, который добавляет свой единственный аргумент object (в вашем конкретном примере список c) к субъекту list. В вашем примере это приводит к c добавлению ссылки на себя (отсюда и бесконечная рекурсия).

Альтернатива конкатенации '+'

Метод list.extend() также является методом мутатора, который объединяет свой аргумент sequence с субъектом list. В частности, он добавляет каждый из элементов sequence в порядке итерации.

в сторону

Будучи оператором, + возвращает результат выражения в виде нового значения. Будучи не цепочечным mutator методом, list.extend() изменяет список тем на месте и ничего не возвращает.

Массивы

Я добавил это из-за потенциальной путаницы, которую может вызвать ответ Авеля выше, смешивая обсуждение списков, последовательностей и массивов. Arrays были добавлены в Python после последовательностей и списков, как более эффективный способ хранения массивов целочисленных типов данных. Не путайте arrays с lists. Они не то же самое.

Из документов массива :

Массивы являются типами последовательностей и ведут себя очень похоже на списки, за исключением того, что тип хранимых в них объектов ограничен. Тип указывается во время создания объекта с помощью кода типа, который представляет собой один символ.

15 голосов
/ 07 января 2010

append добавляет элемент в список. если вы хотите расширить список новым списком, вам нужно использовать extend.

>>> c = [1, 2, 3]
>>> c.extend(c)
>>> c
[1, 2, 3, 1, 2, 3]
8 голосов
/ 07 января 2010

Списки Python разнородны, то есть элементы в одном списке могут быть объектами любого типа. Выражение: c.append(c) добавляет объект c, каким бы он ни был, к списку. В случае, если это делает сам список членом списка.

Выражение c += c складывает два списка вместе и присваивает результат переменной c. Перегруженный оператор + определен в списках для создания нового списка, содержимым которого являются элементы первого списка и элементы второго списка.

Так что это действительно просто разные выражения, используемые для создания разных вещей по замыслу.

6 голосов
/ 07 января 2010

Метод, который вы ищете - extend(). Из документации Python :

list.append(x)
    Add an item to the end of the list; equivalent to a[len(a):] = [x].

list.extend(L)
    Extend the list by appending all the items in the given list; equivalent to a[len(a):] = L.

list.insert(i, x)
    Insert an item at a given position. The first argument is the index of the element before which to insert, so a.insert(0, x) inserts at the front of the list, and a.insert(len(a), x) is equivalent to a.append(x).
2 голосов
/ 07 января 2010

См. документацию :

list.append (х)

  • Добавить элемент в конец списка; эквивалентно [len (a):] = [x].

list.extend (L), - расширить список, добавив все элементы в данный список; эквивалентно [len (a):] = L.

c.append(c) «добавляет» c к себе как элемент . Поскольку список является ссылочным типом, это создает рекурсивную структуру данных.

c += c эквивалентен extend(c), который добавляет элементы c к c.

2 голосов
/ 07 января 2010

вы должны использовать extend ()

>>> c=[1,2,3]
>>> c.extend(c)
>>> c
[1, 2, 3, 1, 2, 3]

другая информация: добавление или расширение

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...