Come cambiare la posizione di due elementi in un elenco Python?


208

Non sono stato in grado di trovare una buona soluzione per questo problema in rete (probabilmente perché switch, position, list e Python sono tutte parole così sovraccaricate).

È piuttosto semplice: ho questo elenco:

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

Vorrei cambiare posizione 'password2'e 'password1'- non conoscendo la loro posizione esatta, solo che sono uno accanto all'altro ed password2è il primo.

Ci sono riuscito con alcuni abbonamenti piuttosto lunghi, ma mi chiedevo che fosse possibile trovare qualcosa di un po 'più elegante?


Il tuo problema è l'efficienza di cercare "password2" nell'elenco? 'Password1' può precedere 'password2'? C'è qualche complessità qui che non si presenta nella tua domanda originale? Altrimenti concordo con @unwind.
Brent scrive il codice

3
Dovresti pubblicare ciò che hai - Sono curioso di sapere cosa intendi con un "abbonamento piuttosto prolisso alla lista".
Samtregar,

Qualcosa sulla falsariga di index1 = index ('password1'); index2 = index ('password2'); order = order [: index2] .append (order [index1]). append (order [index2]). append (order [index1 + 1:]); sparsi su qualche altra riga. Piuttosto no.
mikl

Risposte:


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

Il semplice scambio di Python è simile al seguente:

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

Ora tutto ciò che devi fare è capire cosa iè e che può essere facilmente fatto con index:

i = foo.index("password2")

15

Date le vostre specifiche, utilizzerei l'assegnazione delle sezioni:

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

Il lato destro dell'assegnazione della sezione è una "sezione invertita" e può anche essere scritto:

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

se lo trovi più leggibile, come molti farebbero.


Perché questo non funziona se vuoi cambiare titolo e posta, il primo elemento con il secondo?
Luigi Tiburzi,

Scusa, ora capisco, non ci sono elementi su i-1, quindi viene restituita una lista vuota
Luigi Tiburzi,

7

Come può mai essere più lungo di

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

Questo è solo un semplice scambio usando l'archiviazione temporanea.


13
Se vuoi essere davvero "Pythonic", puoi sempre farlo anche tu:my_list[indexOfPwd2],my_list[indexOfPwd2+1] = my_list[indexOfPwd2+1],my_list[indexOfPwd2]
Brent scrive il codice

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

di conseguenza se l'ultimo elemento è maggiore dell'elemento in posizione i, entrambi vengono scambiati.


-1

puoi usare ad esempio:

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

Non sono un esperto di pitone ma potresti provare: diciamo

i = (1,2)

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

sopra darebbe o / p come:

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

1
Ciò non funziona senza conoscere la posizione dei tasti da scambiare.
mikl
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.