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

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

31.10.2008 05:55:36
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]

5201
6.10.2019 17:39:37
В чем разница extendи просто использование оператора сложения - в приведенном выше примере x = x + [4, 5]?
Rohan 29.05.2017 22:10:07
На самом деле есть большая разница - x + [4, 5]дает вам новый список, назначенный х - x.extend()мутирует оригинальный список. Я уточню в своем ответе здесь ниже.
Aaron Hall♦ 17.07.2017 17:14:55
@AaronHall @Rohan, но это то же самое, что и x += [4,5].
Astitva Srivastava 13.12.2018 14:54:54
@AstitvaSrivastava На самом деле, я думаю, что расширение быстрее с точки зрения байт-кода
MilkyWay90 21.12.2018 16:22:02
Ключевое слово при использовании append- Object . Если вы попытаетесь использовать extendи передадите словарь , он добавит ключ , а не весь хэш в конец массива.
Anthony 15.03.2019 14:53:10

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

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

>>> a = [1, 2, 3]
>>> a.append([4, 5, 6])
>>> a
[1, 2, 3, [4, 5, 6]]
121
31.10.2008 05:57:32

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

>>> li = ['a', 'b', 'mpilgrim', 'z', 'example']
>>> li
['a', 'b', 'mpilgrim', 'z', 'example']

>>> li.append("new")
>>> li
['a', 'b', 'mpilgrim', 'z', 'example', 'new']

>>> li.append(["new", 2])
>>> li
['a', 'b', 'mpilgrim', 'z', 'example', 'new', ['new', 2]]

>>> li.insert(2, "new")
>>> li
['a', 'b', 'new', 'mpilgrim', 'z', 'example', 'new', ['new', 2]]

>>> li.extend(["two", "elements"])
>>> li
['a', 'b', 'new', 'mpilgrim', 'z', 'example', 'new', ['new', 2], 'two', 'elements']
635
4.09.2019 15:28:50

Следующие два фрагмента семантически эквивалентны:

for item in iterator:
    a_list.append(item)

а также

a_list.extend(iterator)

Последнее может быть быстрее, поскольку цикл реализован на языке C.

61
24.11.2016 11:00:44
Расширение на моей машине примерно в 4 раза быстрее, чем в цикле (16 по сравнению с 4 для 100 циклов нулей)
Alex L 27.12.2012 08:29:23
extend()вероятно, предварительно выделяет, а append()скорее нет.
Mad Physicist 23.10.2015 13:43:19
@MadPhysicist: Ради полноты, бывали моменты, когда extend() нельзя разумно предварительно распределить, так как некоторые итерации не реализуются __len__(), но, как и вы, я был бы удивлен, если бы он не попытался. Некоторый выигрыш в производительности также достигается за счет выполнения итерационной части в чистом C, а не в Python, как указано в ответе Аарона .
Soren Bjornstad 28.07.2019 03:43:53

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]
20
5.06.2018 09:16:41
Этот ответ не контрастирует с дополнением и, следовательно, не отвечает на вопрос
pppery 13.07.2018 03:20:44

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]
22
5.06.2018 09:22:31

Вы можете использовать «+» для возврата расширения, вместо расширения на месте.

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заключается в том, когда он используется в областях функций, см. Этот пост в блоге .

37
5.01.2017 10:30:45
Влияет ли использование «+» для возврата расширения на временную сложность?
franklin 19.07.2015 03:59:07
@franklin, подробности смотрите в этом ответе: stackoverflow.com/a/28119966/2230844
denfromufa 21.07.2015 14:50:35
Я не вижу, как это отвечает на вопрос
pppery 13.07.2018 03:20:10

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 .

44
21.05.2019 09:08:03
Вы не можете расширить только с 6, так как это не повторяется. И второй вывод в вашем примере неверен. 'abc' добавляется как один элемент, так как вы передали его в extendвиде списка с одним элементом ['abc']: [1, 2, 3, 4, 5, 'abc']. Для того, чтобы ваш пример вывода правильно, измените Азбуки строку: x.extend('abc'). И удалите x.extend(6)или измените его на x.extend([6]).
aneroid 25.09.2014 09:28:07

Это эквивалент 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]]
19
14.01.2015 19:14:47
Почему нет = +?! Более сжатый
denfromufa 13.09.2015 02:18:57

Интересный момент, который был намекнут, но не объяснен, состоит в том, что расширение быстрее, чем добавление. Любой цикл, который имеет добавление внутри, должен рассматриваться как замененный list.extend (processing_elements).

Имейте в виду, что добавление новых элементов может привести к перераспределению всего списка в лучшее место в памяти. Если это делается несколько раз, потому что мы добавляем 1 элемент за раз, общая производительность страдает. В этом смысле list.extend аналогичен "" .join (stringlist).

12
6.08.2014 12:46:38

Добавить добавляет все данные сразу. Все данные будут добавлены во вновь созданный индекс. С другой стороны, extendкак следует из названия, расширяет текущий массив.

Например

list1 = [123, 456, 678]
list2 = [111, 222]

С appendмы получаем:

result = [123, 456, 678, [111, 222]]

Пока extendмы получаем:

result = [123, 456, 678, 111, 222]
12
9.04.2017 06:29:14

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

  • 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. Они семантически похожи на расширение.

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

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

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

Сложность времени

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

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

Итерация по многочисленным вызовам appendдобавляет сложность, делая ее эквивалентной расширению, и поскольку итерация расширения реализована в C, она всегда будет быстрее, если вы намереваетесь добавлять последовательные элементы из итерируемого в список.

Представление

Вы можете задаться вопросом, что является более производительным, поскольку 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

И мы видим, что выход из нашего пути создания итерируемого простого использования расширения - это (незначительная) трата времени:

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

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

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

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

Вывод

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

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

481
3.10.2018 14:22:29
@ Аарон Холл Один небольшой комментарий в алгоритме синхронизации. "extend_one" может возвращать "немного неправильное" время, потому что создание списка также вовлечено. Вероятно, лучше создать элементы как переменные ( ex1 = 0и ex2 = [0]) и передать эти переменные, если вы хотите быть более строгими.
ilias iliadis 31.03.2018 18:06:48
Идеальный ответ действительно. Как насчет производительности l1 += l2против l1.extend(l2)?
Jean-Francois T. 23.04.2018 03:54:20
@ Жан-Франсуа Т .: l1 += l2и в l1.extend(l2)конечном итоге выполнить тот же код ( list_extendфункция в listobject.c). Единственными отличиями являются: 1. +=переназначение l1(само по себе для lists, но переназначение поддерживает неизменяемые типы, которые не совпадают с объектом после), что делает его недопустимым, если l1на самом деле является атрибутом неизменяемого объекта; например, t = ([],), t[0] += lstпотерпит неудачу, в то время как t[0].extend(lst)будет работать. 2. l1 += l2использует выделенные байт-коды, а l1.extend(l2)использует обобщенный метод диспетчеризации; это делает +=быстрее чем extend.
ShadowRanger 17.08.2018 19:10:51
Тот факт, что +=необходимо переназначить 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)не нужно.
ShadowRanger 17.08.2018 19:20:26
Простое сравнение в локальных тестах: для локальной переменной (то +=есть просто используется STORE_FAST, что очень дешево), где добавляемое значение представляет собой существующее listс одним элементом, с повторением операции 1000 раз, +=в среднем это занимает около 33 нс , в то время как extendзаняло 78 нс, разница 45 нс. Если l1это глобальный (требует более дорогой STORE_GLOBAL), разница сужается до 17 нс. Если l1это на самом деле local.l1(требует еще дороже STORE_ATTR), нет значимой разницы между +=и extend(время примерно одинаковое; extendиногда выигрывает).
ShadowRanger 17.08.2018 19:32:25

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 () : где extension () используется для объединения двух списков или вставки нескольких элементов в один список.

Пример 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]
16
10.10.2017 19:56:19

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]
2
21.05.2019 09:31:49

Я надеюсь, что смогу сделать полезное дополнение к этому вопросу. Если в вашем списке хранится объект определенного типа, например Info, вот ситуация, в которой extendметод не подходит: в forцикле и при Infoкаждом создании объекта и использовании его extendдля сохранения в списке он завершится неудачей. Исключение как ниже:

TypeError: объект 'Info' не повторяется

Но если вы используете appendметод, результат в порядке. Поскольку каждый раз, когда используется extendметод, он всегда будет обрабатывать его как список или любой другой тип коллекции, повторять его и размещать после предыдущего списка. Конкретный объект не может быть повторен, очевидно.

5
9.04.2017 06:55:51

Добавить против Расширить

введите описание изображения здесь

С помощью append вы можете добавить один элемент, который расширит список:

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

Если вы хотите расширить более одного элемента, вы должны использовать extension, потому что вы можете добавить только один элемент или один список элементов:

>>> a.append([4,5])
>>> a
>>> [1,2,3,[4,5]]

Так что вы получите вложенный список

Вместо того, чтобы с расширением, вы можете расширить один элемент, как это

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

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

>>> a.extend([4,5,6])
>>> a
[1,2,3,4,5,6]

Добавление одного элемента с обоими методами

введите описание изображения здесь

добавить 1 элемент

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

расширить один элемент

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

Добавление большего количества элементов ... с разными результатами

Если вы используете append для более чем одного элемента, вы должны передать список элементов в качестве аргументов, и вы получите список NESTED!

>>> 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, чтобы получить список с большим количеством элементов. Вы будете использовать append, чтобы добавлять не больше элементов в список, но один элемент, который является вложенным списком, как вы можете ясно увидеть в выводе кода.

введите описание изображения здесь

введите описание изображения здесь

60
12.09.2019 12:04:24

Различать их интуитивно

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'},
                }
4
7.06.2018 01:44:51

Английский словарь определяет слова 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)
8
12.09.2019 12:02:01

append«расширяет» список (на месте) только одним элементом , переданным одним объектом (в качестве аргумента).

extend«расширяет» список (на месте) на столько элементов, сколько содержится в передаваемом объекте (в качестве аргумента).

Это может быть немного запутанным для strобъектов.

  1. Если вы передадите строку в качестве аргумента: appendв конце добавите один строковый элемент, но extendдобавите столько «одиночных» str-элементов, сколько длина этой строки.
  2. Если вы передадите список строк в качестве аргумента: 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,
0
31.03.2018 18:46:17

Присоединение и расширение являются одним из механизмов расширения в Python.

Добавить: Добавляет элемент в конец списка.

my_list = [1,2,3,4]

Чтобы добавить новый элемент в список, мы можем использовать метод append следующим образом.

my_list.append(5)

Местоположение по умолчанию, в которое будет добавлен новый элемент, всегда находится в позиции (длина + 1).

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

Дескриптор метода вставки (индекс, объект). Он принимает два аргумента: во-первых, это индекс, который мы хотим вставить в наш элемент, а во-вторых, сам элемент.

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]
0
17.07.2018 07:19:35
Почему вы отвечаете на вопрос, на который уже много раз отвечали? Этому вопросу 10 лет ...
Mike - SMT 3.08.2018 13:19:51