Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Better way to swap elements in a list?

Tags:

python

I have a bunch of lists that look like this one:

l = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 

I want to swap elements as follows:

final_l = [2, 1, 4, 3, 6, 5, 8, 7, 10, 9] 

The size of the lists may vary, but they will always contain an even number of elements.

I'm fairly new to Python and am currently doing it like this:

l =  [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] final_l = [] for i in range(0, len(l)/2):     final_l.append(l[2*i+1])     final_l.append(l[2*i]) 

I know this isn't really Pythonic and would like to use something more efficient. Maybe a list comprehension?

like image 562
EliseB Avatar asked Aug 26 '16 13:08

EliseB


People also ask

How do you switch elements in a list?

Store the element at pos1 and pos2 as a pair in a tuple variable, say get. Unpack those elements with pos2 and pos1 positions in that list. Now, both the positions in that list are swapped.

How do you interchange items in a list in Python?

To swap two list elements x and y by value, get the index of their first occurrences using the list. index(x) and list. index(y) methods and assign the result to variables i and j , respectively. Then apply the multiple assignment expression lst[i], lst[j] = lst[j], lst[i] to swap the elements.

How do you swap two elements?

1. Using Collections. swap() method. The standard solution to swap two elements in a List is using the Collections.

Which function is used to swap the contents of a list?

swap() function in C++


2 Answers

No need for complicated logic, simply rearrange the list with slicing and step:

In [1]: l = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]  In [2]: l[::2], l[1::2] = l[1::2], l[::2]  In [3]: l Out[3]: [2, 1, 4, 3, 6, 5, 8, 7, 10, 9] 

 TLDR;

Edited with explanation

I believe most viewers are already familiar with list slicing and multiple assignment. In case you don't I will try my best to explain what's going on (hope I do not make it worse).

To understand list slicing, here already has an excellent answer and explanation of list slice notation. Simply put:

a[start:end] # items start through end-1 a[start:]    # items start through the rest of the array a[:end]      # items from the beginning through end-1 a[:]         # a copy of the whole array  There is also the step value, which can be used with any of the above:  a[start:end:step] # start through not past end, by step 

Let's look at OP's requirements:

 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]  # list l   ^  ^  ^  ^  ^  ^  ^  ^  ^  ^   0  1  2  3  4  5  6  7  8  9    # respective index of the elements l[0]  l[2]  l[4]  l[6]  l[8]      # first tier : start=0, step=2    l[1]  l[3]  l[5]  l[7]  l[9]   # second tier: start=1, step=2 ----------------------------------------------------------------------- l[1]  l[3]  l[5]  l[7]  l[9]    l[0]  l[2]  l[4]  l[6]  l[8]   # desired output 

First tier will be: l[::2] = [1, 3, 5, 7, 9] Second tier will be: l[1::2] = [2, 4, 6, 8, 10]

As we want to re-assign first = second & second = first, we can use multiple assignment, and update the original list in place:

first , second  = second , first 

that is:

l[::2], l[1::2] = l[1::2], l[::2] 

As a side note, to get a new list but not altering original l, we can assign a new list from l, and perform above, that is:

n = l[:]  # assign n as a copy of l (without [:], n still points to l) n[::2], n[1::2] = n[1::2], n[::2] 

Hopefully I do not confuse any of you with this added explanation. If it does, please help update mine and make it better :-)

like image 50
Anzel Avatar answered Sep 22 '22 04:09

Anzel


Here a single list comprehension that does the trick:

In [1]: l = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]  In [2]: [l[i^1] for i in range(len(l))] Out[2]: [2, 1, 4, 3, 6, 5, 8, 7, 10, 9] 

The key to understanding it is the following demonstration of how it permutes the list indices:

In [3]: [i^1 for i in range(10)] Out[3]: [1, 0, 3, 2, 5, 4, 7, 6, 9, 8] 

The ^ is the exclusive or operator. All that i^1 does is flip the least-significant bit of i, effectively swapping 0 with 1, 2 with 3 and so on.

like image 24
NPE Avatar answered Sep 21 '22 04:09

NPE