Вставте елемент із певним індексом у список і поверніть оновлений список


99

У мене є таке:

>>> a = [1, 2, 4]
>>> print a
[1, 2, 4]

>>> print a.insert(2, 3)
None

>>> print a
[1, 2, 3, 4]

>>> b = a.insert(3, 6)
>>> print b
None

>>> print a
[1, 2, 3, 6, 4]

Чи є спосіб отримати оновлений список як результат, замість того, щоб оновити оригінальний список на місці?


11
b = a[:].insert(2,3)здається досить коротким, не впливає на оригінальний список і є досить описовим.
mkoistinen

6
@mkoistinen Для мене це не працює. >>> a = [1, 2, 3, 4] >>> b = a[:].insert(2, 5) >>> print b None
SparkAndShine

Відповіді:


89

l.insert(index, obj)насправді нічого не повертає. Він просто оновлює список.

Як сказав АТО, ви можете це зробити b = a[:index] + [obj] + a[index:]. Однак інший спосіб:

a = [1, 2, 4]
b = a[:]
b.insert(2, 3)

56
Якщо ви не можете терпіти 3 рядки коду, що читається, переведіть його у функцію та викликайте.
IceArdor

54

Найефективніший підхід

Ви також можете вставити елемент за допомогою індексації фрагментів у списку. Наприклад:

>>> a = [1, 2, 4]
>>> insert_at = 2  # Index at which you want to insert item

>>> b = a[:]   # Created copy of list "a" as "b".
               # Skip this step if you are ok with modifying the original list

>>> b[insert_at:insert_at] = [3]  # Insert "3" within "b"
>>> b
[1, 2, 3, 4]

Для вставки декількох елементів разом за даним індексом все, що вам потрібно зробити, це використовувати listдекілька елементів, які потрібно вставити. Наприклад:

>>> a = [1, 2, 4]
>>> insert_at = 2   # Index starting from which multiple elements will be inserted

# List of elements that you want to insert together at "index_at" (above) position
>>> insert_elements = [3, 5, 6]

>>> a[insert_at:insert_at] = insert_elements
>>> a   # [3, 5, 6] are inserted together in `a` starting at index "2"
[1, 2, 3, 5, 6, 4]

Альтернативне використання розуміння списку (але дуже повільне з точки зору продуктивності) :

В якості альтернативи, вона може бути досягнута з допомогою списку розуміння з enumerateтеж. (Але, будь ласка, не робіть це таким чином. Це лише для ілюстрації) :

>>> a = [1, 2, 4]
>>> insert_at = 2

>>> b = [y for i, x in enumerate(a) for y in ((3, x) if i == insert_at else (x, ))]
>>> b
[1, 2, 3, 4]

Порівняння продуктивності всіх рішень

Ось timeitпорівняння всіх відповідей зі списком з 1000 елементів для Python 3.4.5:

  • Моя відповідь із використанням нарізаної вставки - найшвидша (3,08 мкс на петлю)

     mquadri$ python3 -m timeit -s "a = list(range(1000))" "b = a[:]; b[500:500] = [3]"
     100000 loops, best of 3: 3.08 µsec per loop
  • Прийнята відповідь ATOzTOA на основі злиття нарізаних списків - друге (6,71 мкс на цикл)

     mquadri$ python3 -m timeit -s "a = list(range(1000))" "b = a[:500] + [3] + a[500:]"
     100000 loops, best of 3: 6.71 µsec per loop
  • Відповідь Раші Панчала з більшістю голосівlist.insert(...)- третя (26,5 usec за цикл)

     python3 -m timeit -s "a = list(range(1000))" "b = a[:]; b.insert(500, 3)"
     10000 loops, best of 3: 26.5 µsec per loop
  • Моя відповідь із розумінням списку таenumerate- по-четверте (дуже повільно, 168 мкс на цикл)

     mquadri$ python3 -m timeit -s "a = list(range(1000))" "[y for i, x in enumerate(a) for y in ((3, x) if i == 500 else (x, )) ]"
     10000 loops, best of 3: 168 µsec per loop

2
Мені дуже подобається цей результат, оскільки він легко розширюється для вирішення проблеми, а що, якщо я хочу вставити значення 3, 3.5в цей список (по порядку) -> a[2:2] = [3,3.5]. Дуже акуратно
minillinim

1
Як працює [2: 2] = a_list? a [2: 2] в основному починається від 2-го індексу до 1-го індексу (2-1), але в прямому напрямку, що означає порожній [] список. Як воно поширюється? Якщо ми робимо [2: 3: -1], це не спрацьовує.
SamCodes

Чудова відповідь. Цікаво, чи складність найкращого вибору - O (1)? Якщо так, то чому?
Лернер Чжан,

Цю відповідь потрібно оновити. Одного разу я не можу відтворити повідомлення про час, навіть за допомогою Python 3.4 (я отримую коефіцієнт 2 між list.insertприсвоєнням та зрізом), а на Python 3.8 ця різниця повністю зникла. Очевидно, що найяскравіший спосіб вставити елемент - використовувати list.insert.
a_guest

39

Найкоротший я отримав: b = a[:2] + [3] + a[2:]

>>>
>>> a = [1, 2, 4]
>>> print a
[1, 2, 4]
>>> b = a[:2] + [3] + a[2:]
>>> print a
[1, 2, 4]
>>> print b
[1, 2, 3, 4]

Кількість рядків коду не є хорошим показником якості коду. Цей підхід має недоліки як з точки зору продуктивності, так і з причини читабельності.
a_guest

0

Найчистіший підхід - скопіювати список, а потім вставити об’єкт у копію. На Python 3 це можна зробити за допомогою list.copy:

new = old.copy()
new.insert(index, value)

На Python 2 копіювання списку можна здійснити за допомогою new = old[:](це також працює на Python 3).

З точки зору продуктивності немає різниці з іншими запропонованими методами:

$ python --version
Python 3.8.1
$ python -m timeit -s "a = list(range(1000))" "b = a.copy(); b.insert(500, 3)"
100000 loops, best of 5: 2.84 µsec per loop
$ python -m timeit -s "a = list(range(1000))" "b = a.copy(); b[500:500] = (3,)"
100000 loops, best of 5: 2.76 µsec per loop

-1

Використовуйте метод вставки списку Python () . Використання:

# Синтаксис

Синтаксис методу insert () -

list.insert(index, obj)

# Параметри

  • index - це індекс, куди потрібно вставити об'єкт obj.
  • obj - це Об'єкт, який потрібно вставити в даний список.

#Return Value Цей метод не повертає жодного значення, але він вставляє даний елемент із заданим індексом.

Приклад:

a = [1,2,4,5]

a.insert(2,3)

print(a)

Повертається [1, 2, 3, 4, 5]


2
Це не дає відповіді на запитання.
Густав Бертрам,

5
Запитання було конкретним: Is there anyway I can get the updated list as result, instead of updating the original list in place?Ваша відповідь робить протилежне.
Ласловатий
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.