260

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?

mikl
  • 23,749
  • 20
  • 68
  • 89
  • 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. – Brent Writes Code Mar 22 '10 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 Mar 22 '10 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 Mar 22 '10 at 19:06

8 Answers8

480
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]
Tiago Martins Peres
  • 14,289
  • 18
  • 86
  • 145
samtregar
  • 6,888
  • 3
  • 21
  • 17
215

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")
Can Berk Güder
  • 109,922
  • 25
  • 130
  • 137
18

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.

Alex Martelli
  • 854,459
  • 170
  • 1,222
  • 1,395
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.

unwind
  • 391,730
  • 64
  • 469
  • 606
  • 15
    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]` – Brent Writes Code Mar 22 '10 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 .

Aditya
  • 533
  • 3
  • 11
ravi tanwar
  • 598
  • 5
  • 16
-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']
SmartElectron
  • 1,331
  • 1
  • 16
  • 17
-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]
-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)
Trimax
  • 2,413
  • 7
  • 35
  • 59
lambzee
  • 100
  • 2