1

What is the best way to do this:

>>> replace2([1, 2, 3, 4, 5, 6])
[2, 1, 4, 3, 6, 5]
glglgl
  • 89,107
  • 13
  • 149
  • 217
user2160982
  • 189
  • 1
  • 2
  • 10

4 Answers4

8
def replace2inplace(lst):
    lst[1::2], lst[::2] = lst[::2], lst[1::2]

This uses slice assignment and slice step sizes to swap every pair in the list around, in-place:

>>> somelst = [1, 2, 3, 4, 5, 6]
>>> replace2inplace(somelst)
>>> somelst
[2, 1, 4, 3, 6, 5]

Otherwise you could use some itertools tricks:

from itertools import izip, chain

def replace2copy(lst):
    lst1, lst2 = tee(iter(lst), 2)
    return list(chain.from_iterable(izip(lst[1::2], lst[::2])))

which gives:

>>> replace2([1, 2, 3, 4, 5, 6])
[2, 1, 4, 3, 6, 5]

with the list() call optional; if you only need to loop over the result the generator is enough:

from itertools import izip, chain, islice, tee

def replace2gen(lst):
    lst1, lst2 = tee(iter(lst))
    return chain.from_iterable(izip(islice(lst1, 1, None, 2), islice(lst2, None, None, 2)))

for i in replace2gen([1, 2, 3, 4, 5, 6]):
    print i

where replace2gen() can take arbitrary iterators too.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
0

Out-of-place version:

def replace2(lst):
    return [x for pair in zip(lst[1::2], lst[::2]) for x in pair]
Pavel Anossov
  • 60,842
  • 14
  • 151
  • 124
0

My choice:

x = range(1,7)
res = [e for e in itertools.chain(*zip(x[1::2],x[0::2]))]
volcano
  • 3,578
  • 21
  • 28
0
>>> a = [1, 2, 3, 4, 5, 6]
>>> sum([[x+1,x] for x in a if x&1 == True],[])
[2, 1, 4, 3, 6, 5]

EDIT: Some further explanation was requested:

The code steps through each element in the list a and, if the element is odd (x&1 == True) it puts that element and the next element into a list in reverse order ([x+1,x]).

With out the sum(...,[]) function we would have

[[2, 1], [4, 3], [6, 5]]

The sum(...,[]) function removes the internal square brackets giving

[2, 1, 4, 3, 6, 5]

This can be done more generally by using the index of the list rather than its value:

>>> a = [1, 2, 3, 4, 5, 6]
>>> sum([[a[x],a[x-1]] for x in range(len(a)) if x&1 == True],[])
[2, 1, 4, 3, 6, 5]

However, this will remove the last element of the list if its length is not even.

Lee
  • 29,398
  • 28
  • 117
  • 170