В чем разница между методами списка append()
и extend()
?
20 ответов
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]
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']
В чем разница между методами добавления и расширения списка?
append
добавляет свой аргумент как отдельный элемент в конец списка. Длина самого списка увеличится на единицу.extend
перебирает свой аргумент, добавляя каждый элемент в список, расширяя список. Длина списка будет увеличиваться на сколько элементов было в итерируемом аргументе.
append
Метод list.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
Метод list.extend
расширяет список, добавляя элементы из итерируемого:
my_list.extend(iterable)
Таким образом, с расширением каждый элемент итерации добавляется в список. Например:
>>> 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
. Они семантически похожи на extension.
my_list + another_list
создает в памяти третий список, поэтому вы можете вернуть его результат, но для этого требуется, чтобы второй итерируемый объект был списком.
my_list += another_list
изменяет список на месте (это оператор на месте, а списки являются изменяемыми объектами, как мы видели), поэтому он не создает новый список. Он также работает так же, как и extend, в том смысле, что вторая итерация может быть любой итерируемой.
Не запутайтесь - my_list = my_list + another_list
не эквивалентно +=
- он дает вам новый список, назначенный my_list.
Сложность времени
Добавление имеет (амортизированное) постоянная временная сложность, O(1).
Extend имеет временную сложность O (k).
Итерации по множеству вызовов append
усложняются, делая его эквивалентным расширению, и, поскольку итерация расширения реализована в 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 можно использовать для достижения того же результата, что и extension. Следующие функции делают то же самое:
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
И мы видим, что попытки создать итерацию просто для использования extension - это (незначительная) трата времени:
>>> min(timeit.repeat(lambda: append_one([], 0)))
0.2082819009956438
>>> min(timeit.repeat(lambda: extend_one([], 0)))
0.2397019260097295
Из этого мы узнаем, что от использования extend
ничего не получится, когда у нас есть только один элемент для добавления.
Кроме того, эти тайминги не так важны. Я просто показываю им, что в Python выполнение семантически правильных действий означает выполнение действий Правильно Way ™.
Вполне возможно, что вы можете проверить тайминги на двух сопоставимых операциях и получить неоднозначный или обратный результат. Просто сосредоточьтесь на семантически правильных вещах.
Вывод
Мы видим, что extend
семантически более понятен и может работать намного быстрее, чем append
, когда вы собираетесь добавлять каждый элемент итерируемого объекта в список.
Если у вас есть только один элемент (не в итерируемом), который нужно добавить в список, используйте append
.
ex1 = 0
и ex2 = [0]
) и передать эти переменные, если вы хотите быть более строгими.
l1 += l2
по сравнению с l1.extend(l2)
?
l1 += l2
и l1.extend(l2)
в конечном итоге выполняют один и тот же код (функция list_extend
в listobject.c
). Единственные различия: 1. +=
переназначает l1
(самому себе для list
s, но переназначение поддерживает неизменяемые типы, которые не являются одним и тем же объектом после), что делает его незаконным, если l1
на самом деле является атрибутом неизменяемого объекта; например, t = ([],)
, t[0] += lst
не сработает, а t[0].extend(lst)
будет работать. 2. l1 += l2
использует выделенные байт-коды, а l1.extend(l2)
использует обобщенный метод диспетчеризации; это делает +=
быстрее, чем extend
.
+=
должен переназначить l1
, действительно означает, что в некоторых случаях более медленная отправка extend
частично или полностью компенсируется отсутствием повторного назначения для левой стороны. Например, если list
является атрибутом объекта, self.l1 += l2
и self.l1.extend(l2)
имеют одинаковую производительность в моей установке Python 3.6 просто потому, что реальная операция больше похожа на self.l1 = self.l1.__iadd__(l2)
, это означает, что он должен выполнять умеренно дорогостоящий STORE_ATTR
, в котором self.l1.extend(l2)
не должен.
+=
просто использует STORE_FAST
, что очень дешево), где добавляемым значением является существующий list
с одним элементом в если операция повторяется 1000 раз, на +=
в среднем ушло около 33 нс, а на extend
- 78 нс, то есть разница в 45 нс. Если l1
является глобальным (требуется более дорогой STORE_GLOBAL
), разница уменьшается до 17 нс. Если l1
на самом деле является local.l1
(требуется еще более дорогой STORE_ATTR
), значимой разницы между +=
и extend
нет (время примерно одинаково; extend
иногда выигрывает).
append
добавляет один элемент. extend
добавляет список элементов.
Обратите внимание, что если вы передадите список для добавления, он все равно добавит один элемент:
>>> a = [1, 2, 3]
>>> a.append([4, 5, 6])
>>> a
[1, 2, 3, [4, 5, 6]]
Добавить vs Расширить
С помощью append вы можете добавить один элемент, который расширит список:
>>> a = [1,2]
>>> a.append(3)
>>> a
[1,2,3]
Если вы хотите расширить более одного элемента, вам следует использовать расширение, потому что вы можете добавить только один элемент или один список элементов:
>>> a.append([4,5])
>>> a
>>> [1,2,3,[4,5]]
Чтобы у вас получился вложенный список
Вместо этого вы можете расширить один элемент следующим образом
>>> a = [1,2]
>>> a.extend([3])
>>> a
[1,2,3]
Или, по-другому, от добавления, расширить несколько элементов за один раз, не вкладывая список в исходный (это причина расширения имени)
>>> a.extend([4,5,6])
>>> a
[1,2,3,4,5,6]
Добавление одного элемента обоими методами
Как append, так и extend могут добавить один элемент в конец списка, хотя append проще.
Добавить 1 элемент
>>> x = [1,2]
>>> x.append(3)
>>> x
[1,2,3]
Расширить один элемент
>>> x = [1,2]
>>> x.extend([3])
>>> x
[1,2,3]
Добавление дополнительных элементов ... с разными результатами
Если вы используете добавление более чем для одного элемента, вам нужно передать список элементов в качестве аргументов, и вы получите ВЛОЖЕННЫЙ список!
>>> x = [1,2]
>>> x.append([3,4])
>>> x
[1,2,[3,4]]
Вместо этого с расширением вы передаете список в качестве аргумента, но вы получите список с новым элементом, который не вложен в старый.
>>> z = [1,2]
>>> z.extend([3,4])
>>> z
[1,2,3,4]
Итак, с большим количеством элементов вы будете использовать extension, чтобы получить список с большим количеством элементов. Однако добавление списка не приведет к добавлению дополнительных элементов в список, а только к одному элементу, который является вложенным списком, как вы можете ясно видеть в выходных данных кода.
Следующие два фрагмента семантически эквивалентны:
for item in iterator:
a_list.append(item)
А также
a_list.extend(iterator)
Последнее может быть быстрее, поскольку цикл реализован в C.
extend()
, вероятно, выделяется заранее, а append()
- нет.
extend()
не может разумно выполнить предварительное выделение, поскольку некоторые итерации не реализуют __len__()
, но, как и вы, я бы удивлен, если не попробует. Некоторый выигрыш в производительности также достигается за счет выполнения итерационной части на чистом C вместо Python, как указано в ответе Аарона.
Метод append()
добавляет один элемент в конец списка.
x = [1, 2, 3]
x.append([4, 5])
x.append('abc')
print(x)
# gives you
[1, 2, 3, [4, 5], 'abc']
Метод extend()
принимает один аргумент, список, и добавляет каждый из элементов аргумента в исходный список. (Списки реализованы как классы. «Создание» списка на самом деле создает экземпляр класса. Таким образом, список имеет методы, которые работают с ним.)
x = [1, 2, 3]
x.extend([4, 5])
x.extend('abc')
print(x)
# gives you
[1, 2, 3, 4, 5, 'a', 'b', 'c']
Из Погрузитесь в Python .
extend
как список с одним элементом ['abc']
: [1, 2, 3, 4, 5, 'abc']. Чтобы ваш пример вывода был правильным, измените строку abc на: x.extend('abc')
. И удалите x.extend(6)
или измените его на x.extend([6])
.
Вы можете использовать "+" для возврата расширения вместо расширения на месте.
l1=range(10)
l1+[11]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11]
l2=range(10,1,-1)
l1+l2
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 9, 8, 7, 6, 5, 4, 3, 2]
Аналогично +=
для поведения на месте, но с небольшими отличиями от append
и extend
. Одно из самых больших отличий +=
от append
и extend
заключается в том, что он используется в областях видимости функций, см. это сообщение в блоге .
list.extend([item])
более эффективен, чем list.append(item)
append(object)
обновляет список, добавляя объект в список.
x = [20]
# List passed to the append(object) method is treated as a single object.
x.append([21, 22, 23])
# Hence the resultant list length will be 2
print(x)
--> [20, [21, 22, 23]]
extend(list)
по существу объединяет два списка.
x = [20]
# The parameter passed to extend(list) method is treated as a list.
# Eventually it is two lists being concatenated.
x.extend([21, 22, 23])
# Here the resultant list's length is 4
print(x)
--> [20, 21, 22, 23]
Это эквивалент append
и extend
с использованием оператора +
:
>>> x = [1,2,3]
>>> x
[1, 2, 3]
>>> x = x + [4,5,6] # Extend
>>> x
[1, 2, 3, 4, 5, 6]
>>> x = x + [[7,8]] # Append
>>> x
[1, 2, 3, 4, 5, 6, [7, 8]]
extend()
можно использовать с аргументом итератора. Вот пример. Вы хотите составить список из списка списков следующим образом:
Из
list2d = [[1,2,3],[4,5,6], [7], [8,9]]
Вы хотите
>>>
[1, 2, 3, 4, 5, 6, 7, 8, 9]
Вы можете использовать для этого itertools.chain.from_iterable()
. Результатом этого метода является итератор. Его реализация эквивалентна
def from_iterable(iterables):
# chain.from_iterable(['ABC', 'DEF']) --> A B C D E F
for it in iterables:
for element in it:
yield element
Вернемся к нашему примеру, мы можем сделать
import itertools
list2d = [[1,2,3],[4,5,6], [7], [8,9]]
merged = list(itertools.chain.from_iterable(list2d))
И получите список разыскиваемых.
Вот как эквивалентно extend()
можно использовать с аргументом итератора:
merged = []
merged.extend(itertools.chain.from_iterable(list2d))
print(merged)
>>>
[1, 2, 3, 4, 5, 6, 7, 8, 9]
append () : в основном используется в Python для добавления одного элемента.
Пример 1:
>> a = [1, 2, 3, 4]
>> a.append(5)
>> print(a)
>> a = [1, 2, 3, 4, 5]
Пример 2:
>> a = [1, 2, 3, 4]
>> a.append([5, 6])
>> print(a)
>> a = [1, 2, 3, 4, [5, 6]]
extend () : где extend () используется для объединения двух списков или вставки нескольких элементов в один список.
Пример 1:
>> a = [1, 2, 3, 4]
>> b = [5, 6, 7, 8]
>> a.extend(b)
>> print(a)
>> a = [1, 2, 3, 4, 5, 6, 7, 8]
Пример 2:
>> a = [1, 2, 3, 4]
>> a.extend([5, 6])
>> print(a)
>> a = [1, 2, 3, 4, 5, 6]
Интересный момент, на который намекали, но не объясняли, заключается в том, что расширение выполняется быстрее, чем добавление. Любой цикл, который имеет добавление внутри, следует рассматривать как замененный на list.extend (loaded_elements).
Имейте в виду, что добавление новых элементов может привести к перераспределению всего списка в лучшее место в памяти. Если это сделать несколько раз, потому что мы добавляем по одному элементу за раз, общая производительность снизится. В этом смысле list.extend аналогичен "" .join (stringlist).
Добавить добавляет сразу все данные. Все данные будут добавлены во вновь созданный индекс. С другой стороны, extend
, как следует из названия, расширяет текущий массив.
Например
list1 = [123, 456, 678]
list2 = [111, 222]
С append
мы получаем:
result = [123, 456, 678, [111, 222]]
На extend
мы получаем:
result = [123, 456, 678, 111, 222]
Английский словарь определяет слова append
и extend
как:
добавить : добавить (что-нибудь) в конец письменного документа.
расширить : увеличить. Увеличить или расширить
Обладая этими знаниями, теперь давайте разберемся
1) Разница между append
и extend
append
:
- Добавляет любой объект Python как есть в конец списка (т. Е. Как последний элемент в списке).
- Результирующий список может быть вложенным и содержать разнородные элементы (например, список, строку, кортеж, словарь, набор и т. Д.).
extend
:
- Принимает любой итерабельный в качестве аргумента и делает список больше .
- Результирующий список всегда является одномерным (т.е. без вложенности), и он может содержать в себе разнородные элементы (например, символы, целые числа, числа с плавающей запятой) в результате применения
list(iterable)
.
2) Сходство между append
и extend
- Оба приводят ровно один аргумент.
- Оба изменяют список на месте .
- В результате оба возвращают
None
.
Пример
lis = [1, 2, 3]
# 'extend' is equivalent to this
lis = lis + list(iterable)
# 'append' simply appends its argument as the last element to the list
# as long as the argument is a valid Python object
list.append(object)
Надеюсь, что смогу внести полезное дополнение к этому вопросу. Если в вашем списке хранится объект определенного типа, например Info
, вот ситуация, в которой метод extend
не подходит: в цикле for
и генерации объекта Info
каждый раз, используя extend
для сохранения его в вашем списке, он терпит неудачу. Исключение, как показано ниже:
TypeError: объект Info не повторяется
Но если вы используете метод append
, результат нормальный. Поскольку каждый раз, используя метод extend
, он всегда будет рассматривать его как список или любой другой тип коллекции, перебирать его и помещать после предыдущего списка. Очевидно, что конкретный объект не может быть повторен.
Чтобы различать их интуитивно
l1 = ['a', 'b', 'c']
l2 = ['d', 'e', 'f']
l1.append(l2)
l1
['a', 'b', 'c', ['d', 'e', 'f']]
Это как l1
воспроизвести тело внутри своего тела (вложенное).
# Reset l1 = ['a', 'b', 'c']
l1.extend(l2)
l1
['a', 'b', 'c', 'd', 'e', 'f']
Это похоже на то, что два отдельных человека женятся и создают единую семью.
Кроме того, для вашей справки я составляю исчерпывающий список всех методов списка.
list_methods = {'Add': {'extend', 'append', 'insert'},
'Remove': {'pop', 'remove', 'clear'}
'Sort': {'reverse', 'sort'},
'Search': {'count', 'index'},
'Copy': {'copy'},
}
extend(L)
расширяет список, добавляя все элементы в данном списке L
.
>>> a
[1, 2, 3]
a.extend([4]) #is eqivalent of a[len(a):] = [4]
>>> a
[1, 2, 3, 4]
a = [1, 2, 3]
>>> a
[1, 2, 3]
>>> a[len(a):] = [4]
>>> a
[1, 2, 3, 4]
append
«расширяет» список (на месте) на только один элемент , единственный переданный объект (в качестве аргумента).
extend
«расширяет» список (на месте) на столько элементов, сколько содержит переданный объект (в качестве аргумента).
Это может немного сбивать с толку для объектов str
.
- Если вы передадите строку в качестве аргумента:
append
добавит одну строку в конце, ноextend
добавит столько "одиночных" элементов 'str', сколько длина этой строки. - Если вы передадите список строк в качестве аргумента:
append
все равно добавит один элемент "список" в конец иextend
добавит столько элементов списка, сколько длина переданного списка.
def append_o(a_list, element): a_list.append(element) print('append:', end = ' ') for item in a_list: print(item, end = ',') print() def extend_o(a_list, element): a_list.extend(element) print('extend:', end = ' ') for item in a_list: print(item, end = ',') print() append_o(['ab'],'cd') extend_o(['ab'],'cd') append_o(['ab'],['cd', 'ef']) extend_o(['ab'],['cd', 'ef']) append_o(['ab'],['cd']) extend_o(['ab'],['cd'])
Производит:
append: ab,cd,
extend: ab,c,d,
append: ab,['cd', 'ef'],
extend: ab,cd,ef,
append: ab,['cd'],
extend: ab,cd,
Добавление и расширение - это один из механизмов расширяемости в Python.
Добавить: добавляет элемент в конец списка.
my_list = [1,2,3,4]
Чтобы добавить новый элемент в список, мы можем использовать метод append следующим образом.
my_list.append(5)
Местоположение по умолчанию, в которое будет добавлен новый элемент, всегда находится в позиции (длина + 1).
Insert: метод вставки использовался для преодоления ограничений добавления. С помощью insert мы можем явно определить точную позицию, в которую мы хотим, чтобы наш новый элемент был вставлен.
Дескриптор метода вставки (индекс, объект). Он принимает два аргумента: первый - это индекс, который мы хотим вставить, а второй - сам элемент.
Example: my_list = [1,2,3,4]
my_list[4, 'a']
my_list
[1,2,3,4,'a']
Расширить: это очень полезно, когда мы хотим объединить два или более списков в один. Без расширения, если мы хотим объединить два списка, результирующий объект будет содержать список списков.
a = [1,2]
b = [3]
a.append(b)
print (a)
[1,2,[3]]
Если мы попытаемся получить доступ к элементу на позиции 2, мы получим список ([3]) вместо элемента. Чтобы объединить два списка, нам нужно будет использовать append.
a = [1,2]
b = [3]
a.extend(b)
print (a)
[1,2,3]
Чтобы присоединиться к нескольким спискам
a = [1]
b = [2]
c = [3]
a.extend(b+c)
print (a)
[1,2,3]
Похожие вопросы
Связанные вопросы
Новые вопросы
python
Python — это мультипарадигмальный многоцелевой язык программирования с динамической типизацией. Он предназначен для быстрого изучения, понимания и использования, а также обеспечивает чистый и унифицированный синтаксис. Обратите внимание, что Python 2 официально не поддерживается с 01.01.2020. Если у вас есть вопросы о версии Python, добавьте тег [python-2.7] или [python-3.x]. При использовании варианта Python (например, Jython, PyPy) или библиотеки (например, Pandas, NumPy) укажите это в тегах.
extend
и простым использованием оператора сложения - в приведенном выше примереx = x + [4, 5]
?x + [4, 5]
дает вам новый список, назначенный x -x.extend()
изменяет исходный список. Я уточняю в своем ответе ниже.x += [4,5]
.append
- Объект . Если вы попытаетесь использоватьextend
и передадите словарь , он добавит ключ , а не весь хеш в конец массива.