Better way to swap elements in a list?
<p>I have a bunch of lists that look like this one:</p>

<pre><code>l = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
</code></pre>

<p>I want to swap elements as follows:</p>

<pre><code>final_l = [2, 1, 4, 3, 6, 5, 8, 7, 10, 9]
</code></pre>

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

<p>I'm fairly new to Python and am currently doing it like this:</p>

<pre><code>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])
</code></pre>

<p>I know this isn't really <a href="https://en.wiktionary.org/wiki/Pythonic#Adjective">Pythonic</a> and would like to use something more efficient. Maybe a list comprehension?</p>

<h2>A benchmark between top answers:</h2>

<p>Python 2.7:</p>

<pre><code>('inp1 -&gt;', 15.302665948867798) # NPE's answer 
('inp2a -&gt;', 10.626379013061523) # alecxe's answer with chain
('inp2b -&gt;', 9.739919185638428) # alecxe's answer with chain.from_iterable
('inp3 -&gt;', 2.6654279232025146) # Anzel's answer
</code></pre>

<p>Python 3.4:</p>

<pre><code>inp1 -&gt; 7.913498195000102
inp2a -&gt; 9.680125927000518
inp2b -&gt; 4.728151862000232
inp3 -&gt; 3.1804273489997286
</code></pre>

<p>If you are curious about the different performances between python 2 and 3, here are the reasons:</p>

<p>As you can see @NPE's answer (<code>inp1</code>) performs very better in python3.4, the reason is that in python3.X <code>range()</code> is a smart object and doesn't preserve all the items between that range in memory like a list.</p>

<blockquote>
  <p>In many ways the object returned by <code>range()</code> behaves as if it is a list, but in fact it isnât. It is an object which returns the successive items of the desired sequence when you iterate over it, but it doesnât really make the list, thus saving space.</p>
</blockquote>

<p>And that's why in python 3 it doesn't return a list while you slice the range object.</p>

<pre><code># python2.7
&gt;&gt;&gt; range(10)[2:5]
[2, 3, 4]
# python 3.X
&gt;&gt;&gt; range(10)[2:5]
range(2, 5)
</code></pre>

<p>The second significant change is performance accretion of the third approach (<code>inp3</code>). As you can see the difference between it and the last solution has decreased to ~2sec (from ~7sec). The reason is because of the <code>zip()</code> function which in python3.X it returns an iterator which produces the items on demand. And since the <code>chain.from_iterable()</code> needs to iterate over the items once again it's completely redundant to do it before that too (what that <code>zip</code> does in python 2). </p>

<p>Code:</p>

<pre><code>from timeit import timeit


inp1 = """
[l[i^1] for i in range(len(l))]
   """
inp2a = """
list(chain(*zip(l[1::2], l[0::2])))
"""
inp2b = """
list(chain.from_iterable(zip(l[1::2], l[0::2])))
"""
inp3 = """
l[::2], l[1::2] = l[1::2], l[::2]
"""

lst = list(range(100000))
print('inp1 -&gt;', timeit(stmt=inp1,
                        number=1000,
                        setup="l={}".format(lst)))
print('inp2a -&gt;', timeit(stmt=inp2a,
                        number=1000,
                        setup="l={}; from itertools import chain".format(lst)))
print('inp2b -&gt;', timeit(stmt=inp2b,
                        number=1000,
                        setup="l={}; from itertools import chain".format(lst)))
print('inp3 -&gt;', timeit(stmt=inp3,
                        number=1000,
                        setup="l={}".format(lst)))
</code></pre>

python