Jak zmienić pozycję dwóch elementów na liście Python?

208

Nie udało mi się znaleźć dobrego rozwiązania tego problemu w sieci (prawdopodobnie dlatego, że przełącznik, pozycja, lista i Python to takie przeciążone słowa).

To raczej proste - mam tę listę:

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

Chciałbym zmienić pozycję 'password2'i 'password1'- nie znając ich dokładnej pozycji, tyle tylko, że są tuż obok siebie i password2są pierwsi.

Osiągnąłem to z dość długim indeksowaniem list, ale zastanawiałem się, czy można wymyślić coś bardziej eleganckiego?

mikl
źródło
Czy Twoim problemem jest skuteczność próby znalezienia „hasła2” na liście? Czy „hasło1” może znajdować się przed „hasłem2”? Czy jest tu jakaś złożoność, która nie pojawia się w twoim pierwotnym pytaniu? W przeciwnym razie zgadzam się z @unwind.
Brent pisze kod
3
Powinieneś opublikować to, co masz - ciekawi mnie, co rozumiesz przez „dość skomplikowane indeksowanie list”.
samtregar
Coś w stylu indeksu1 = indeks („hasło1”); indeks2 = indeks („hasło2”); order = order [: index2] .append (order [index1]). append (order [index2]). append (order [index1 + 1:]); rozłożone na kilka kolejnych linii. Dość, nie.
mikl

Odpowiedzi:

392
    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]
samtregar
źródło
165

Prosta zamiana Pythona wygląda następująco:

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

Teraz wszystko, co musisz zrobić, to dowiedzieć się, co ijest, i można to łatwo zrobić za pomocą index:

i = foo.index("password2")
Czy Berk Güder
źródło
15

Biorąc pod uwagę twoje specyfikacje, użyłbym przypisania plasterka:

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

Prawa strona przypisania plasterka jest „odwróconym plasterkiem” i może być również pisana:

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

jeśli uznasz to za bardziej czytelne, tak jak wielu.

Alex Martelli
źródło
Dlaczego to nie działa, jeśli chcesz zmienić tytuł i pocztę, pierwszy element na drugi?
Luigi Tiburzi
Niestety teraz rozumiem, nie ma żadnych elementów w I-1 tak zwracany jest pusta lista
Luigi Tiburzi
7

Jak to może być kiedykolwiek dłuższe niż

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

To zwykła zamiana przy użyciu tymczasowego magazynu.

rozwijać
źródło
13
Jeśli chcesz być naprawdę „pytoniczny”, zawsze możesz to zrobić:my_list[indexOfPwd2],my_list[indexOfPwd2+1] = my_list[indexOfPwd2+1],my_list[indexOfPwd2]
Brent pisze kod
0
for i in range(len(arr)):
    if l[-1] > l[i]:
        l[-1], l[i] = l[i], l[-1]
        break

w wyniku tego, jeśli ostatni element jest większy niż element w pozycji, iwówczas oba zostaną zamienione.

ravi tanwar
źródło
-1

możesz użyć na przykład:

>>> 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']
SmartElectron
źródło
-1

Nie jestem ekspertem w pythonie, ale możesz spróbować: powiedz

i = (1,2)

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

powyżej dałoby o / p jako:

res(1, 2) = (2,1)
lambzee
źródło
1
To nie działa bez znajomości położenia klawiszy do zamiany.
mikl