Вставить элемент по определенному индексу в список и вернуть обновленный список

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

Ответы:

90

l.insert(index, obj)на самом деле ничего не возвращает. Он просто обновляет список.

Как сказали в АТО, можно b = a[:index] + [obj] + a[index:]. Однако другой способ:

a = [1, 2, 4]
b = a[:]
b.insert(2, 3)
Раши Панчал
источник
56
Если вы не можете терпеть 3 строки читаемого кода, поместите их в функцию и вызовите ее.
IceArdor 01
56

Самый эффективный подход

Вы также можете вставить элемент, используя индексирование фрагментов в списке. Например:

>>> 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 мксек за цикл)

     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
Гость
источник
-2

Используйте метод Python list insert () . Использование:

#Синтаксис

Синтаксис метода 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?ваш ответ обратный.
Laszlowaty