В чем разница между методами добавления списков и расширения?
.append() добавляет свой аргумент в виде отдельного элемента в конец списка. Длина самого списка увеличится на единицу.
.extend() выполняет итерацию по своему аргументу, добавляя каждый элемент в список, расширяя список. Длина списка увеличится на то, сколько элементов было в итеративном аргументе.
.append()
Метод .append() добавляет объект в конец списка.
my_list.append(object)
Каким бы ни был объект, будь то число, строка, другой список или что-то еще, он добавляется в конец my_list как отдельная запись в списке.
Поэтому имейте в виду, что список - это объект. Если вы добавите другой список в список, первым списком будет отдельный объект в конце списка (что может быть не тем, что вы хотите):
>>> 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 каждый элемент итерируемого добавляется в список. Например:
Имейте в виду, что строка является итерируемой, поэтому, если вы расширяете список строкой, вы будете добавлять каждый символ по мере выполнения итерации по строке (что может быть не тем, что вы хотите):
Перегрузка операторов, __add__ (+) и __iadd__ (+=)
Оба оператора + и += определены для list. Они семантически похожи на extend .
my_list + another_list создает третий список в памяти, поэтому вы можете вернуть его результат, но для этого требуется, чтобы вторая итерация была списком.
my_list += another_list изменяет список на месте (это является оператором на месте, а списки являются изменяемыми объектами, как мы видели), поэтому он не создает новый список. Это также работает как extend , в том смысле, что второй итерируемый объект может быть любым типом итерируемого объекта.
Не запутывайтесь - my_list = my_list + another_list не эквивалентно += - это дает вам совершенно новый список, назначенный my_list .
Повторение нескольких вызовов .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 . Следующие функции делают то же самое.:
defappend(alist, iterable): for item in iterable: alist.append(item)
Идеальный ответ, я просто упускаю момент сравнения добавления только одного элемента
Делайте семантически правильные действия. Если вы хотите добавить все элементы в итерируемый объект, используйте .extend(). Если вы добавляете только один элемент, используйте .append().
Хорошо, давайте проведем эксперимент, чтобы увидеть, как это работает со временем:
defextend_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 - это (незначительная) трата времени:
Из этого мы узнаем, что использование .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]]