Вопрос-Ответ

What is the difference between Python's list methods append and extend?

В чем разница между методами добавления списков в Python и расширения?

В чем разница между методами списка append() и extend()?

Переведено автоматически
Ответ 1

.append() добавляет указанный объект в конец списка:

>>> x = [1, 2, 3]
>>> x.append([4, 5])
>>> print(x)
[1, 2, 3, [4, 5]]

.extend() расширяет список, добавляя элементы из указанного итерируемого:

>>> x = [1, 2, 3]
>>> x.extend([4, 5])
>>> print(x)
[1, 2, 3, 4, 5]
Ответ 2

.append() добавляет элемент в список,
тогда как .extend() объединяет первый список с другим списком / итерируемым.

>>> xs = ['A', 'B']
>>> xs
['A', 'B']

>>> xs.append("D")
>>> xs
['A', 'B', 'D']

>>> xs.append(["E", "F"])
>>> xs
['A', 'B', 'D', ['E', 'F']]

>>> xs.insert(2, "C")
>>> xs
['A', 'B', 'C', 'D', ['E', 'F']]

>>> xs.extend(["G", "H"])
>>> xs
['A', 'B', 'C', 'D', ['E', 'F'], 'G', 'H']
Ответ 3

В чем разница между методами добавления списков и расширения?



  • .append() добавляет свой аргумент в виде отдельного элемента в конец списка. Длина самого списка увеличится на единицу.

  • .extend() выполняет итерацию по своему аргументу, добавляя каждый элемент в список, расширяя список. Длина списка увеличится на то, сколько элементов было в итеративном аргументе.

.append()

Метод .append() добавляет объект в конец списка.

my_list.append(object) 

Каким бы ни был объект, будь то число, строка, другой список или что-то еще, он добавляется в конец my_list как отдельная запись в списке.

>>> my_list
['foo', 'bar']
>>> my_list.append('baz')
>>> my_list
['foo', 'bar', 'baz']

Поэтому имейте в виду, что список - это объект. Если вы добавите другой список в список, первым списком будет отдельный объект в конце списка (что может быть не тем, что вы хотите):

>>> another_list = [1, 2, 3]
>>> my_list.append(another_list)
>>> my_list
['foo', 'bar', 'baz', [1, 2, 3]]
#^^^^^^^^^--- single item at the end of the list.

.extend()

.extend() Метод расширяет список, добавляя элементы из итерируемого списка.:

my_list.extend(iterable)

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

>>> my_list
['foo', 'bar']
>>> another_list = [1, 2, 3]
>>> my_list.extend(another_list)
>>> my_list
['foo', 'bar', 1, 2, 3]

Имейте в виду, что строка является итерируемой, поэтому, если вы расширяете список строкой, вы будете добавлять каждый символ по мере выполнения итерации по строке (что может быть не тем, что вы хотите):

>>> my_list.extend('baz')
>>> my_list
['foo', 'bar', 1, 2, 3, 'b', 'a', 'z']

Перегрузка операторов, __add__ (+) и __iadd__ (+=)

Оба оператора + и += определены для list. Они семантически похожи на extend .

my_list + another_list создает третий список в памяти, поэтому вы можете вернуть его результат, но для этого требуется, чтобы вторая итерация была списком.

my_list += another_list изменяет список на месте (это является оператором на месте, а списки являются изменяемыми объектами, как мы видели), поэтому он не создает новый список. Это также работает как extend , в том смысле, что второй итерируемый объект может быть любым типом итерируемого объекта.

Не запутывайтесь - my_list = my_list + another_list не эквивалентно += - это дает вам совершенно новый список, назначенный my_list .

Временная сложность

Append имеет (амортизированную) постоянную временную сложность, O (1).

Расширение имеет временную сложность, O (k).

Повторение нескольких вызовов .append() увеличивает сложность, что делает его эквивалентным повторению extend , а поскольку итерация extend реализована на C, она всегда будет быстрее, если вы собираетесь добавлять последовательные элементы из итерируемого элемента в список.

Что касается "амортизированного" - из источника реализации объекта списка:

    /* This over-allocates proportional to the list size, making room
* for additional growth. The over-allocation is mild, but is
* enough to give linear-time amortized behavior over a long
* sequence of appends() in the presence of a poorly-performing
* system realloc().

Это означает, что мы получаем преимущества от предварительного перераспределения памяти большего размера, чем необходимо, но мы можем заплатить за это при следующем незначительном перераспределении еще большим объемом. Общее время для всех добавлений линейно равно O (n), и это время, выделяемое на добавление, становится O (1).

Производительность

Вы можете задаться вопросом, какой из них более производителен, поскольку append можно использовать для достижения того же результата, что и extend . Следующие функции делают то же самое.:

def append(alist, iterable):
for item in iterable:
alist.append(item)

def extend(alist, iterable):
alist.extend(iterable)

Итак, давайте рассчитаем их время:

import timeit

>>> min(timeit.repeat(lambda: append([], "abcdefghijklmnopqrstuvwxyz")))
2.867846965789795
>>> min(timeit.repeat(lambda: extend([], "abcdefghijklmnopqrstuvwxyz")))
0.8060121536254883

Обращение к комментарию о таймингах

Один из комментаторов сказал:


Идеальный ответ, я просто упускаю момент сравнения добавления только одного элемента


Делайте семантически правильные действия. Если вы хотите добавить все элементы в итерируемый объект, используйте .extend(). Если вы добавляете только один элемент, используйте .append().

Хорошо, давайте проведем эксперимент, чтобы увидеть, как это работает со временем:

def append_one(a_list, element):
a_list.append(element)

def extend_one(a_list, element):
"""creating a new list is semantically the most direct
way to create an iterable to give to extend"""

a_list.extend([element])

import timeit

И мы видим, что стараться изо всех сил создавать итерацию только для использования extend - это (незначительная) трата времени:

>>> min(timeit.repeat(lambda: append_one([], 0)))
0.2082819009956438
>>> min(timeit.repeat(lambda: extend_one([], 0)))
0.2397019260097295

Из этого мы узнаем, что использование .extend() когда у нас есть только один элемент для добавления, ничего не дает.

Кроме того, эти тайминги не так уж важны. Я просто показываю их, чтобы подчеркнуть, что в Python выполнение семантически правильных действий означает выполнение вещей правильным способом ™.

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

Заключение

Мы видим, что .extend() это семантически понятнее и что оно может выполняться намного быстрее, чем .append(), когда вы собираетесь добавлять каждый элемент в итерируемом списке.

Если у вас есть только один элемент (не в виде итерации) для добавления в список, используйте .append().

Ответ 4

append добавляет один элемент. extend добавляет список элементов.

Обратите внимание, что если вы передаете список в append , он все равно добавляет один элемент:

>>> a = [1, 2, 3]
>>> a.append([4, 5, 6])
>>> a
[1, 2, 3, [4, 5, 6]]
python list