¿Mover un elemento dentro de una lista?

104

En Python, ¿cómo muevo un elemento a un índice definido en una lista?

Gabriele Cirulli
fuente

Respuestas:

160

Utilice el insertmétodo de una lista:

l = list(...)
l.insert(index, item)

Alternativamente, puede usar una notación de sector:

l[index:index] = [item]

Si desea mover un elemento que ya está en la lista a la posición especificada, tendrá que eliminarlo e insertarlo en la nueva posición:

l.insert(newindex, l.pop(oldindex))
David Z
fuente
22
Solo tenga en cuenta que mover un elemento que ya está en una lista con el método insert / pop tendrá un comportamiento diferente dependiendo de si se mueve hacia el frente o hacia atrás de la lista. Moviéndose hacia la izquierda, inserta antes del objeto que ha elegido. Moviéndose hacia la parte posterior que inserta después del elemento que ha elegido. Verifique que se mueva al final de la lista (error de índice).
MKaras
¿Cómo mover varios elementos? Dada una lista a = [1,2,3,4,5,6,7,8,9], cómo transformarla en [1,2, [3,4,5], 6,7,8,9 ]? ¿Se puede hacer esto en un solo paso o con una lista de comprensión?
g33kz0r
@MKaras Probé esto con Python 3.5 y PUEDES insertarlo last index + 1sin errores. En ese caso, el elemento simplemente se agrega a la lista.
user2061057
@ user2061057 es correcto :) incluso los índices grandes resultarán en elementos insertados al final. a.insert(99999, 1) In [14]: a Out[14]: [...., 1]
lee penkman
1
Para aquellos que intentan usar el índice -1 para insertar el elemento al final, deben usar len (l) en su lugar.
nda
31

Una solución un poco más corta, que solo mueve el artículo hasta el final, no a ninguna parte es esta:

l += [l.pop(0)]

Por ejemplo:

>>> l = [1,2,3,4,5]
>>> l += [l.pop(0)]
>>> l
[2, 3, 4, 5, 1]
Tim
fuente
13
También podrías usar l.append(l.pop(0)). Es solo un poco más largo, pero es mucho más legible.
coredumperror
¿Cómo podría moverlo al principio?
19

Si no conoce la posición del elemento, es posible que primero deba buscar el índice:

old_index = list1.index(item)

luego muévelo:

list1.insert(new_index, list1.pop(old_index))

o en mi humilde opinión de una manera más limpia:

try:
  list1.remove(item)
  list1.insert(new_index, item)
except ValueError:
  pass
nngeek
fuente
6
Creo que tengo razón en sentir vergüenza por su passdeclaración ... nunca oculte las excepciones: lo predeterminado en un ejemplo como este debería ser proporcionar una declaración de error más limpia o una declaración de impresión ... raise ValueError(f'Unable to move item to {new_index}')o print(f'Moving item to {new_index} failed. List remains unchanged.'). Tal vez passestaría bien si se llamara a una función try_to_move_itemo algo para que se entendiera que la operación podría fallar silenciosamente.
flutefreak7
3

Una solución muy sencilla, pero hay que conocer el índice de la posición original y el índice de la nueva posición:

list1[index1],list1[index2]=list1[index2],list1[index1]
V.Petretto
fuente
6
Esto es un intercambio, no un movimiento.
juzzlin
0

He perfilado algunos métodos para mover un elemento dentro de la misma lista con timeit. Estos son los que se deben usar si j> i:

┌──────────┬──────────────────────┐
│ 14.4usec │ x [i: i] = x.pop (j), │
│ 14.5usec │ x [i: i] = [x.pop (j)] │
│ 15.2usec │ x.insertar (i, x.pop (j)) │
└──────────┴──────────────────────┘

y aquí los que se deben usar si j <= i:

┌──────────┬───────────────────────────┐
│ 14.4usec │ x [i: i] = x [j] ,; del x [j] │
│ 14.4usec │ x [i: i] = [x [j]]; del x [j] │
│ 15.4usec │ x.insertar (i, x [j]); del x [j] │
└──────────┴───────────────────────────┘

No es una gran diferencia si solo lo usa unas pocas veces, pero si hace cosas pesadas como la clasificación manual, es importante tomar la más rápida. De lo contrario, recomendaría simplemente tomar el que crea que es más legible.

Músicas de Riedler
fuente