Comment changer la position de deux éléments dans une liste Python?


208

Je n'ai pas été en mesure de trouver une bonne solution à ce problème sur le net (probablement parce que switch, position, list et Python sont tous de tels mots surchargés).

C'est assez simple - j'ai cette liste:

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

Je voudrais changer de position 'password2'et 'password1'- ne connaissant pas leur position exacte, seulement qu'ils sont juste à côté l'un de l'autre etpassword2 sont les premiers.

J'ai accompli cela avec une liste d'indexation assez longue, mais je me demandais s'il était possible de trouver quelque chose d'un peu plus élégant?


Votre problème est-il l'efficacité d'essayer de trouver «mot de passe2» dans la liste? 'Password1' peut-il précéder 'password2'? Y a-t-il ici une certaine complexité qui ne ressort pas de votre question initiale? Sinon, je suis d'accord avec @unwind.
Brent écrit

3
Vous devriez poster ce que vous avez - je suis curieux de savoir ce que vous entendez par "une liste d'indexation assez longue".
samtregar

Quelque chose dans le sens de index1 = index ('password1'); index2 = index ('mot de passe2'); order = order [: index2] .append (order [index1]). append (order [index2]). append (order [index1 + 1:]); répartis sur quelques lignes supplémentaires. Joli, non.
mikl

Réponses:


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

Le swap Python simple ressemble à ceci:

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

Maintenant, tout ce que vous avez à faire est de comprendre ce qui iest, et cela peut facilement être fait avec index:

i = foo.index("password2")

15

Compte tenu de vos spécifications, j'utiliserais l'attribution de tranche:

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

Le côté droit de l'affectation de tranche est une "tranche inversée" et pourrait également être orthographié:

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

si vous trouvez cela plus lisible, comme beaucoup le feraient.


Pourquoi cela ne fonctionne-t-il pas si vous souhaitez changer de titre et de courrier, le premier élément avec le second?
Luigi Tiburzi

Désolé, je comprends maintenant, il n'y a aucun élément à i-1, donc une liste vide est retournée
Luigi Tiburzi

7

Comment peut-il être plus long que

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

C'est juste un échange simple utilisant un stockage temporaire.


13
Si vous voulez être vraiment "Pythonic" à ce sujet, vous pouvez toujours le faire aussi:my_list[indexOfPwd2],my_list[indexOfPwd2+1] = my_list[indexOfPwd2+1],my_list[indexOfPwd2]
Brent écrit le code

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

à la suite de cela, si le dernier élément est supérieur à l'élément en position, iils sont tous les deux échangés.


-1

vous pouvez utiliser par exemple:

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

Je ne suis pas un expert en python mais vous pourriez essayer: dites

i = (1,2)

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

ci-dessus donnerait o / p comme:

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

1
Cela ne fonctionne pas sans connaître la position des touches à échanger.
mikl
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.