Insertar un elemento en un índice específico en una lista y devolver la lista actualizada

99

Tengo esto:

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

¿Hay alguna forma de obtener la lista actualizada como resultado, en lugar de actualizar la lista original en su lugar?

ATOzTOA
fuente
11
b = a[:].insert(2,3)parece bastante corto, no afecta a la lista original y es bastante descriptivo.
mkoistinen
6
@mkoistinen No me funciona. >>> a = [1, 2, 3, 4] >>> b = a[:].insert(2, 5) >>> print b None
SparkAndShine

Respuestas:

89

l.insert(index, obj)en realidad no devuelve nada. Simplemente actualiza la lista.

Como dijo ATO, puede hacerlo b = a[:index] + [obj] + a[index:]. Sin embargo, otra forma es:

a = [1, 2, 4]
b = a[:]
b.insert(2, 3)
Rushy Panchal
fuente
56
Si no puede tolerar 3 líneas de código legible, colóquelo en una función y llámelo.
IceArdor
54

El enfoque más eficiente en rendimiento

También puede insertar el elemento utilizando la indexación de sectores en la lista. Por ejemplo:

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

Para insertar varios elementos juntos en un índice determinado , todo lo que necesita hacer es usar uno listde los múltiples elementos que desea insertar. Por ejemplo:

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

Alternativa usando la comprensión de listas (pero muy lenta en términos de rendimiento) :

Como alternativa, también se puede lograr utilizando la comprensión de listas con enumerate. (Pero no lo haga de esta manera. Es solo para ilustrar) :

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

Comparación de rendimiento de todas las soluciones

Aquí está la timeitcomparación de todas las respuestas con la lista de 1000 elementos para Python 3.4.5:

  • Respuesta mía usando inserción en rodajas: la más rápida (3,08 µseg por ciclo)

     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
  • Respuesta aceptada de ATOzTOA basada en la combinación de listas divididas - Segundo (6,71 µseg por ciclo)

     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
  • La respuesta de Rushy Panchal con la mayoría de los votos usandolist.insert(...)- Tercero (26.5 usec por ciclo)

     python3 -m timeit -s "a = list(range(1000))" "b = a[:]; b.insert(500, 3)"
     10000 loops, best of 3: 26.5 µsec per loop
  • Mi respuesta con List Comprehension yenumerate- Cuarto (muy lento con 168 µseg por ciclo)

     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
Moinuddin Quadri
fuente
2
Realmente me gusta este resultado porque se extiende fácilmente para resolver el problema, ¿qué pasa si quiero insertar los valores 3, 3.5en esa lista (en orden) -> a[2:2] = [3,3.5]. Muy ordenado
minillinim
1
¿Cómo funciona una [2: 2] = a_list? a [2: 2] está básicamente comenzando desde el segundo índice al primer índice (2-1) pero en dirección hacia adelante, lo que significa una lista [] vacía. ¿Cómo se extiende? Si lo hacemos [2: 3: -1] no funciona.
SamCodes
Gran respuesta. Me pregunto si la complejidad de la mejor opción es O (1). Si es así, ¿por qué?
Lerner Zhang
Esta respuesta debe actualizarse. Por una vez, no puedo reproducir los tiempos informados incluso con Python 3.4 (obtengo un factor 2 entre una list.insertasignación de corte), y en Python 3.8 esta diferencia se ha desvanecido por completo. La forma más clara de insertar un elemento es utilizar list.insert, obviamente.
a_guest
39

Lo más corto que tengo: 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]
ATOzTOA
fuente
El número de líneas de código no es una buena medida de la calidad del código. Este enfoque es defectuoso por razones de rendimiento y legibilidad.
a_guest
0

El enfoque más limpio es copiar la lista y luego insertar el objeto en la copia. En Python 3, esto se puede hacer a través de list.copy:

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

En Python 2 se puede copiar la lista a través de new = old[:](esto también funciona en Python 3).

En términos de rendimiento, no hay diferencia con otros métodos propuestos:

$ 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
un invitado
fuente
-1

Utilice el método insert () de la lista de Python . Uso:

#Sintaxis

La sintaxis del método insert () -

list.insert(index, obj)

#Parámetros

  • index: este es el índice donde se debe insertar el objeto obj.
  • obj: este es el objeto que se insertará en la lista dada.

#Return Value Este método no devuelve ningún valor, pero inserta el elemento dado en el índice dado.

Ejemplo:

a = [1,2,4,5]

a.insert(2,3)

print(a)

Devoluciones [1, 2, 3, 4, 5]

Arjun Sanchala
fuente
2
Esto no responde a la pregunta.
Gustav Bertram
5
La pregunta era específica: Is there anyway I can get the updated list as result, instead of updating the original list in place?tu respuesta hace lo contrario.
Laszlowaty