264

I haven’t been able to find a good solution for this problem on the net (probably because switch, position, list and Python are all such overloaded words).

It’s rather simple – I have this list:

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

I’d like to switch position of 'password2' and 'password1' – not knowing their exact position, only that they’re right next to one another and password2 is first.

I’ve accomplished this with some rather long-winded list-subscripting, but I wondered its possible to come up with something a bit more elegant?

3
  • Is your problem the efficiency of trying to find 'password2' in the list? Can 'password1' come before 'password2'? Is there some complexity here that doesn't come across in your original question? Otherwise I agree with @unwind. Commented Mar 22, 2010 at 16:31
  • 3
    You should post what you've got - I'm curious about what you mean by a "rather long-winded list-subscripting."
    – samtregar
    Commented Mar 22, 2010 at 16:33
  • Something along the lines of index1 = index('password1'); index2 = index('password2'); order = order[:index2].append(order[index1]).append(order[index2]).append(order[index1 + 1:]); spread on a few more lines. Pretty, no.
    – mikl
    Commented Mar 22, 2010 at 19:06

8 Answers 8

491
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]
0
222

The simple Python swap looks like this:

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

Now all you need to do is figure what i is, and that can easily be done with index:

i = foo.index("password2")
0
19

Given your specs, I'd use 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']

The right-hand side of the slice assignment is a "reversed slice" and could also be spelled:

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

if you find that more readable, as many would.

2
  • 1
    Why this is not working if you want to switch title and mail, the first element with the second? Commented Oct 26, 2013 at 14:29
  • @LuigiTiburzi because when the slice-end is negative it is taken from the end of the list ie L[1:-1:-1] == L[1:7:-1] which does not work and should be L[1:-9:-1] or L[1::-1] (don't ask, I'm just starting with python and tried stuff) ~ use L[i:i+2] = L[i+1:-len(L)+(i-1):-1] instead (0 <= i <= len(L)-2).
    – MAZ
    Commented Apr 21 at 21:28
8

How can it ever be longer than

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

That's just a plain swap using temporary storage.

1
  • 16
    If you want to be really "Pythonic" about it, you could always do this too: my_list[indexOfPwd2],my_list[indexOfPwd2+1] = my_list[indexOfPwd2+1],my_list[indexOfPwd2] Commented Mar 22, 2010 at 16:32
0
for i in range(len(arr)):
    if l[-1] > l[i]:
        l[-1], l[i] = l[i], l[-1]
        break

as a result of this if last element is greater than element at position i then they both get swapped .

-1

you can use for example:

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

How to swap every element in a list with the next

  for i in range(len(list)):
    try:
      list[i+1]
    except IndexError:
      continue  
    else:
      list[i],list[i+1] = list[i+1],list[i]
1
  • This does not swap every element with next. It just pushes first element to the last position.
    – Azhar Khan
    Commented Nov 8, 2022 at 14:03
-2

I am not an expert in python but you could try: say

i = (1,2)

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

above would give o/p as:

res(1, 2) = (2,1)
1
  • 2
    That does not work without knowing the position of the keys to swap.
    – mikl
    Commented Aug 6, 2016 at 13:00

Not the answer you're looking for? Browse other questions tagged or ask your own question.