Питання Різниця між методами додавання та розширення у Python


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


2689
2017-10-31 05:55


походження




Відповіді:


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]


4089
2017-10-31 06:02



Яка різниця між extend і просто використовуючи оператор додавання - у наведеному вище прикладі x = x + [4, 5]? - Rohan
Насправді там є велика різниця - x + [4, 5] дає вам новий список, присвоєний x - x.extend() змінює оригінальний список. Я докладно описую свою відповідь нижче. - Aaron Hall♦


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.insert(2, "new")
>>> li
['a', 'b', 'new', 'mpilgrim', 'z', 'example', 'new']

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

Від Зануртесь в Python.


525
2017-10-31 05:57





У чому полягає різниця між методами списків додавання та розширення?

  • append додає аргумент як єдиний елемент до кінця списку. Довжина самого списку збільшиться на одиницю.
  • extend повторює аргумент додавання кожного елемента до списку, розширення списку. Довжина списку збільшиться, однак багато елементів були в ітерабельний аргумент.

append

The 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 on end of list.

extend

The 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 додає складності, роблячи його еквівалентним тому, що розширюється, і оскільки ітерація extend's реалізована в C, вона завжди буде швидше, якщо ви збираєтесь додати послідовні елементи з ітерабельного до списку.

Продуктивність

Ви можете задатися питанням, що є більш продуктивним, оскільки додавання може використовуватися для досягнення такого ж результату, як розширення. Наступні функції виконують одне і те ж:

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.


268
2018-01-23 22:44



Відмінна відповідь: я просто не вистачає часу порівняння, додавши лише один елемент - David Sánchez
@Aaron Hall Один невеликий коментар до алгоритму для часу. "extend_one" може повернути "трохи невірний" час, оскільки також включається створення списку. Напевно, краще створити елементи як змінні (ex1 = 0 і ex2 = [0]) і передайте ці змінні, якщо хочете бути більш строгим. - ilias iliadis
Ідеальна відповідь насправді. А як щодо продуктивності l1 += l2 проти l1.extend(l2)? - Jean-Francois T.


append додає один елемент. extend додає список елементів.

Зауважте, що якщо ви передаєте список для додавання, він додає ще один елемент:

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

92
2017-10-31 05:57





Два наступні фрагменти семантично еквівалентні:

for item in iterator:
    a_list.append(item)

і

a_list.extend(iterator)

Останній може бути швидшим, оскільки цикл реалізований у C.


42
2017-08-20 21:11



Розширення ~ 4x швидше на моєму комп'ютері, ніж додавання в циклі (16US проти 4US за 100 петель нулів) - Alex L
extend() ймовірно, попередньо виділяє, поки append() напевно ні. - Mad Physicist


Ви можете використовувати "+" для повернення розширення, а не розширення на місці.

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 це коли він використовується в області функцій, див це повідомлення в блозі.


29
2017-08-26 11:21



Чи використовує "+" для повернення продовження впливає на складність часу? - franklin
@franklin, докладніше дивіться цю відповідь: stackoverflow.com/a/28119966/2230844 - denfromufa
Я не бачу, як це відповідає на питання - ppperry


Метод 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.


29
2017-10-31 13:12



Ви не можете продовжити лише 6, оскільки це не ітерабельно. І другий вихід у вашому прикладі неправильний. 'abc' додано як окремий елемент після того, як ви його передали extend як список з одним елементом ['abc']: [1, 2, 3, 4, 5, 'abc']. Щоб вивести правильний приклад, змініть рядок abc на: x.extend('abc'). І видаліть x.extend(6) або змінити його на x.extend([6]). - aneroid


 Додати до розширення

enter image description here

З додаванням ви можете додати один елемент, який розширюватиме список:

>>> 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]

 Додавання одного елемента за допомогою обох методів

enter image description here

 додати 1 елемент

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

 продовжити один елемент

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

 Додавання інших елементів ... з різними результатами

Якщо ви використовуєте додавання для декількох елементів, ви повинні передати список елементів як аргументи, і ви отримаєте список 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]

Таким чином, з більшою кількістю елементів ви будете використовувати розширення, щоб отримати список з більшою кількістю елементів. Ви будете використовувати append, щоб додати не більше елементів до списку, але один елемент, який є вкладеного списку, як ви можете чітко бачити на виході коду.

enter image description here

enter image description here


17
2017-10-18 07:33



Це найкраща відповідь - Billal BEGUERADJ


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]

16
2018-05-12 19:51





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]

15
2018-05-12 18:21



Ця відповідь не суперечить розширенню додавання і тому не відповідає на питання - ppperry