¿Cómo cambiar la posición de dos elementos en una lista de Python?


208

No he podido encontrar una buena solución para este problema en la red (probablemente porque interruptor, posición, lista y Python son palabras tan sobrecargadas).

Es bastante simple: tengo esta lista:

['title', 'email', 'password2', 'password1', 'first_name', 'last_name', 'next', 'newsletter']

Me gustaría cambiar la posición de 'password2'y 'password1', sin saber su posición exacta, solo que están uno al lado del otro y password2son los primeros.

He logrado esto con algunos suscriptores de lista bastante largos, pero me preguntaba si es posible llegar a algo un poco más elegante.


¿Es su problema la eficiencia de tratar de encontrar 'contraseña2' en la lista? ¿Puede 'contraseña1' ir antes que 'contraseña2'? ¿Hay alguna complejidad aquí que no se encuentre en su pregunta original? De lo contrario, estoy de acuerdo con @unwind.
Brent escribe el código el

3
Debería publicar lo que tiene: tengo curiosidad sobre lo que quiere decir con una "suscripción de lista bastante larga".
samtregar

Algo similar a index1 = index ('contraseña1'); index2 = index ('contraseña2'); order = order [: index2] .append (order [index1]). append (order [index2]). append (order [index1 + 1:]); se extendió en unas pocas líneas más. Bonita no
mikl 22/03/10

Respuestas:


393
    i = ['title', 'email', 'password2', 'password1', 'first_name', 
         'last_name', 'next', 'newsletter']
    a, b = i.index('password2'), i.index('password1')
    i[b], i[a] = i[a], i[b]

165

El simple intercambio de Python se ve así:

foo[i], foo[j] = foo[j], foo[i]

Ahora todo lo que necesita hacer es calcular qué ies, y eso se puede hacer fácilmente con index:

i = foo.index("password2")

15

Dadas sus especificaciones, usaría la asignación de corte:

>>> L = ['title', 'email', 'password2', 'password1', 'first_name', 'last_name', 'next', 'newsletter']
>>> i = L.index('password2')
>>> L[i:i+2] = L[i+1:i-1:-1]
>>> L
['title', 'email', 'password1', 'password2', 'first_name', 'last_name', 'next', 'newsletter']

El lado derecho de la asignación de corte es un "corte invertido" y también podría escribirse:

L[i:i+2] = reversed(L[i:i+2])

si lo encuentra más legible, como muchos lo harían.


¿Por qué esto no funciona si desea cambiar el título y el correo, el primer elemento con el segundo?
Luigi Tiburzi

Lo siento, ahora entiendo, no hay elementos en i-1, por lo que se devuelve una lista vacía
Luigi Tiburzi

7

¿Cómo puede ser más largo que

tmp = my_list[indexOfPwd2]
my_list[indexOfPwd2] = my_list[indexOfPwd2 + 1]
my_list[indexOfPwd2 + 1] = tmp

Eso es solo un intercambio simple usando almacenamiento temporal.


13
Si quieres ser realmente "Pythonic" al respecto, siempre puedes hacer esto también:my_list[indexOfPwd2],my_list[indexOfPwd2+1] = my_list[indexOfPwd2+1],my_list[indexOfPwd2]
Brent escribe el código el

0
for i in range(len(arr)):
    if l[-1] > l[i]:
        l[-1], l[i] = l[i], l[-1]
        break

Como resultado de esto, si el último elemento es mayor que el elemento en la posición i, ambos se intercambian.


-1

puedes usar por ejemplo:

>>> test_list = ['title', 'email', 'password2', 'password1', 'first_name',
                 'last_name', 'next', 'newsletter']
>>> reorder_func = lambda x: x.insert(x.index('password2'),  x.pop(x.index('password2')+1))
>>> reorder_func(test_list)
>>> test_list
... ['title', 'email', 'password1', 'password2', 'first_name', 'last_name', 'next', 'newsletter']

-1

No soy un experto en python, pero podrías intentar: decir

i = (1,2)

res = lambda i: (i[1],i[0])
print 'res(1, 2) = {0}'.format(res(1, 2)) 

arriba daría o / p como:

res(1, 2) = (2,1)

1
Eso no funciona sin conocer la posición de las teclas para intercambiar.
mikl
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.