Как поменять положение двух элементов в списке Python?

208

Я не смог найти хорошего решения для этой проблемы в сети (вероятно, потому что switch, position, list и Python - все такие перегруженные слова).

Это довольно просто - у меня есть этот список:

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

Я хотел бы поменять положение 'password2'и 'password1'- не зная их точного положения, только то, что они находятся рядом друг с другом и стоят на password2первом месте.

Я достиг этого с помощью довольно многословной подписки на списки, но мне было интересно, можно ли придумать что-нибудь более элегантное?

Mikl
источник
Является ли ваша проблема эффективностью попытки найти 'password2' в списке? Может ли «пароль1» предшествовать «паролю2»? Есть ли здесь какая-то сложность, которая не встречается в вашем первоначальном вопросе? В противном случае я согласен с @unwind.
Брент пишет код
3
Вы должны опубликовать то, что у вас есть - мне любопытно, что вы подразумеваете под «довольно скучной подпиской на списки».
Самтрегар
Что-то в духе index1 = index ('password1'); index2 = index ('password2'); order = order [: index2] .append (order [index1]). append (order [index2]). append (order [index1 + 1:]); распределить еще на несколько строк. Довольно, нет.
Микл

Ответы:

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]
samtregar
источник
165

Простой обмен Python выглядит следующим образом:

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

Теперь все, что вам нужно сделать, это выяснить, что iесть, и это можно легко сделать с помощью index:

i = foo.index("password2")
Can Berk Güder
источник
15

Учитывая ваши характеристики, я бы использовал slice-assignment:

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

Правая часть назначения среза является «перевернутым срезом» и также может быть записана:

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

если вы найдете это более читабельным, как многие.

Алекс Мартелли
источник
Почему это не работает, если вы хотите поменять заголовок и почту, первый элемент со вторым?
Луиджи Тибурзи
Извините, теперь я понимаю, что в i-1 нет элементов, поэтому возвращается пустой список
Луиджи Тибурци,
7

Как это может быть дольше, чем

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

Это просто простой обмен с использованием временного хранилища.

размотать
источник
13
Если вы хотите быть действительно "Pythonic" об этом, вы всегда можете сделать это тоже:my_list[indexOfPwd2],my_list[indexOfPwd2+1] = my_list[indexOfPwd2+1],my_list[indexOfPwd2]
Брент пишет код
0
for i in range(len(arr)):
    if l[-1] > l[i]:
        l[-1], l[i] = l[i], l[-1]
        break

в результате этого, если последний элемент больше, чем элемент в позиции, iони оба меняются местами.

Рави Танвар
источник
-1

Вы можете использовать, например:

>>> 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
источник
-1

Я не эксперт в Python, но вы можете попробовать: скажем

i = (1,2)

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

выше даст o / p как:

res(1, 2) = (2,1)
lambzee
источник
1
Это не работает, не зная положение ключей для обмена.
Микл