<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
		>
<channel>
	<title>Comments on: Python value swap</title>
	<atom:link href="http://eikke.com/python-value-swap/feed/" rel="self" type="application/rss+xml" />
	<link>http://eikke.com/python-value-swap/</link>
	<description>&#039;cause this is what I do</description>
	<lastBuildDate>Tue, 20 Jul 2010 21:44:33 +0100</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
		<item>
		<title>By: Nicolas</title>
		<link>http://eikke.com/python-value-swap/comment-page-1/#comment-20934</link>
		<dc:creator>Nicolas</dc:creator>
		<pubDate>Thu, 30 Apr 2009 17:03:38 +0000</pubDate>
		<guid isPermaLink="false">http://eikke.com/?p=103#comment-20934</guid>
		<description>Hmh, rather stupid typo ;-) Thanks for noticing.</description>
		<content:encoded><![CDATA[<p>Hmh, rather stupid typo <img src='http://eikke.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' />  Thanks for noticing.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Chris</title>
		<link>http://eikke.com/python-value-swap/comment-page-1/#comment-20933</link>
		<dc:creator>Chris</dc:creator>
		<pubDate>Thu, 30 Apr 2009 16:58:23 +0000</pubDate>
		<guid isPermaLink="false">http://eikke.com/?p=103#comment-20933</guid>
		<description>...:     tmp = a
   ...:     a = b
   ...:     b = a

Not that it matters, but the result of this is a = b, and b = b</description>
		<content:encoded><![CDATA[<p>&#8230;:     tmp = a<br />
   &#8230;:     a = b<br />
   &#8230;:     b = a</p>
<p>Not that it matters, but the result of this is a = b, and b = b</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: James Henstridge</title>
		<link>http://eikke.com/python-value-swap/comment-page-1/#comment-20733</link>
		<dc:creator>James Henstridge</dc:creator>
		<pubDate>Thu, 23 Apr 2009 14:27:56 +0000</pubDate>
		<guid isPermaLink="false">http://eikke.com/?p=103#comment-20733</guid>
		<description>I guess I was wrong for modern versions of Python.  It&#039;s good to see that the cleanest looking solution is now the most efficient (and seems to have been since at least 2.4).</description>
		<content:encoded><![CDATA[<p>I guess I was wrong for modern versions of Python.  It&#8217;s good to see that the cleanest looking solution is now the most efficient (and seems to have been since at least 2.4).</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Nicolas</title>
		<link>http://eikke.com/python-value-swap/comment-page-1/#comment-20727</link>
		<dc:creator>Nicolas</dc:creator>
		<pubDate>Thu, 23 Apr 2009 08:12:44 +0000</pubDate>
		<guid isPermaLink="false">http://eikke.com/?p=103#comment-20727</guid>
		<description>James: I think you&#039;re wrong here (in the case of swapping 2 variables).

&lt;code&gt;&lt;pre&gt;In [1]: def f():
   ...:     a = 1
   ...:     b = 2
   ...:     
   ...:     tmp = a
   ...:     a = b
   ...:     b = a
   ...: 

In [2]: def g():
   ...:     a = 1
   ...:     b = 2
   ...:     
   ...:     a, b = b, a
   ...: 

In [3]: %timeit f()
1000000 loops, best of 3: 568 ns per loop

In [4]: %timeit g()
1000000 loops, best of 3: 546 ns per loop

In [5]: %timeit f()
1000000 loops, best of 3: 591 ns per loop

In [6]: %timeit g()
1000000 loops, best of 3: 543 ns per loop

In [7]: %timeit f()
1000000 loops, best of 3: 588 ns per loop

In [8]: %timeit g()
1000000 loops, best of 3: 515 ns per loop&lt;/pre&gt;&lt;/code&gt;

The reason is obvious when looking at the opcodes generated by the compiler (which is an optimization of the general system using tuple pack/unpack):

&lt;code&gt;&lt;pre&gt;In [10]: dis.dis(f)
  2           0 LOAD_CONST               1 (1)
              3 STORE_FAST               0 (a)

  3           6 LOAD_CONST               2 (2)
              9 STORE_FAST               1 (b)

  5          12 LOAD_FAST                0 (a)
             15 STORE_FAST               2 (tmp)

  6          18 LOAD_FAST                1 (b)
             21 STORE_FAST               0 (a)

  7          24 LOAD_FAST                0 (a)
             27 STORE_FAST               1 (b)
             30 LOAD_CONST               0 (None)
             33 RETURN_VALUE&lt;/pre&gt;&lt;/code&gt;

&lt;code&gt;&lt;pre&gt;In [11]: dis.dis(g)
  2           0 LOAD_CONST               1 (1)
              3 STORE_FAST               0 (a)

  3           6 LOAD_CONST               2 (2)
              9 STORE_FAST               1 (b)

  5          12 LOAD_FAST                1 (b)
             15 LOAD_FAST                0 (a)
             18 ROT_TWO             
             19 STORE_FAST               0 (a)
             22 STORE_FAST               1 (b)
             25 LOAD_CONST               0 (None)
             28 RETURN_VALUE&lt;/pre&gt;&lt;/code&gt;

The unoptimized case:
&lt;code&gt;&lt;pre&gt;In [12]: def h():
   ....:     a, b, c, d = d, c, b, a
   ....: 

In [13]: dis.dis(h)
  2           0 LOAD_FAST                0 (d)
              3 LOAD_FAST                1 (c)
              6 LOAD_FAST                2 (b)
              9 LOAD_FAST                3 (a)
             12 BUILD_TUPLE              4
             15 UNPACK_SEQUENCE          4
             18 STORE_FAST               3 (a)
             21 STORE_FAST               2 (b)
             24 STORE_FAST               1 (c)
             27 STORE_FAST               0 (d)
             30 LOAD_CONST               0 (None)
             33 RETURN_VALUE&lt;/pre&gt;&lt;/code&gt;</description>
		<content:encoded><![CDATA[<p>James: I think you&#8217;re wrong here (in the case of swapping 2 variables).</p>
<p><code>
<pre>In [1]: def f():
   ...:     a = 1
   ...:     b = 2
   ...:
   ...:     tmp = a
   ...:     a = b
   ...:     b = a
   ...: 

In [2]: def g():
   ...:     a = 1
   ...:     b = 2
   ...:
   ...:     a, b = b, a
   ...: 

In [3]: %timeit f()
1000000 loops, best of 3: 568 ns per loop

In [4]: %timeit g()
1000000 loops, best of 3: 546 ns per loop

In [5]: %timeit f()
1000000 loops, best of 3: 591 ns per loop

In [6]: %timeit g()
1000000 loops, best of 3: 543 ns per loop

In [7]: %timeit f()
1000000 loops, best of 3: 588 ns per loop

In [8]: %timeit g()
1000000 loops, best of 3: 515 ns per loop</pre>
<p></code></p>
<p>The reason is obvious when looking at the opcodes generated by the compiler (which is an optimization of the general system using tuple pack/unpack):</p>
<p><code>
<pre>In [10]: dis.dis(f)
  2           0 LOAD_CONST               1 (1)
              3 STORE_FAST               0 (a)

  3           6 LOAD_CONST               2 (2)
              9 STORE_FAST               1 (b)

  5          12 LOAD_FAST                0 (a)
             15 STORE_FAST               2 (tmp)

  6          18 LOAD_FAST                1 (b)
             21 STORE_FAST               0 (a)

  7          24 LOAD_FAST                0 (a)
             27 STORE_FAST               1 (b)
             30 LOAD_CONST               0 (None)
             33 RETURN_VALUE</pre>
<p></code></p>
<p><code>
<pre>In [11]: dis.dis(g)
  2           0 LOAD_CONST               1 (1)
              3 STORE_FAST               0 (a)

  3           6 LOAD_CONST               2 (2)
              9 STORE_FAST               1 (b)

  5          12 LOAD_FAST                1 (b)
             15 LOAD_FAST                0 (a)
             18 ROT_TWO
             19 STORE_FAST               0 (a)
             22 STORE_FAST               1 (b)
             25 LOAD_CONST               0 (None)
             28 RETURN_VALUE</pre>
<p></code></p>
<p>The unoptimized case:<br />
<code>
<pre>In [12]: def h():
   ....:     a, b, c, d = d, c, b, a
   ....: 

In [13]: dis.dis(h)
  2           0 LOAD_FAST                0 (d)
              3 LOAD_FAST                1 (c)
              6 LOAD_FAST                2 (b)
              9 LOAD_FAST                3 (a)
             12 BUILD_TUPLE              4
             15 UNPACK_SEQUENCE          4
             18 STORE_FAST               3 (a)
             21 STORE_FAST               2 (b)
             24 STORE_FAST               1 (c)
             27 STORE_FAST               0 (d)
             30 LOAD_CONST               0 (None)
             33 RETURN_VALUE</pre>
<p></code></p>
]]></content:encoded>
	</item>
	<item>
		<title>By: James Henstridge</title>
		<link>http://eikke.com/python-value-swap/comment-page-1/#comment-20708</link>
		<dc:creator>James Henstridge</dc:creator>
		<pubDate>Thu, 23 Apr 2009 00:56:05 +0000</pubDate>
		<guid isPermaLink="false">http://eikke.com/?p=103#comment-20708</guid>
		<description>If you benchmark it, you&#039;ll find that the first version using the temporary variable is faster than the second version.  This isn&#039;t too surprising when you realise that it creates a tuple object then has to pull the values out of the tuple object and finally destroy it.

This isn&#039;t to say that tuple unpacking isn&#039;t useful -- if you&#039;ve already got a tuple and you want to assign its items to variables it is a very convenient language feature.</description>
		<content:encoded><![CDATA[<p>If you benchmark it, you&#8217;ll find that the first version using the temporary variable is faster than the second version.  This isn&#8217;t too surprising when you realise that it creates a tuple object then has to pull the values out of the tuple object and finally destroy it.</p>
<p>This isn&#8217;t to say that tuple unpacking isn&#8217;t useful &#8212; if you&#8217;ve already got a tuple and you want to assign its items to variables it is a very convenient language feature.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Nicolas</title>
		<link>http://eikke.com/python-value-swap/comment-page-1/#comment-20706</link>
		<dc:creator>Nicolas</dc:creator>
		<pubDate>Thu, 23 Apr 2009 00:29:40 +0000</pubDate>
		<guid isPermaLink="false">http://eikke.com/?p=103#comment-20706</guid>
		<description>Marius: Thanks, didn&#039;t know that one!</description>
		<content:encoded><![CDATA[<p>Marius: Thanks, didn&#8217;t know that one!</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Marius Gedminas</title>
		<link>http://eikke.com/python-value-swap/comment-page-1/#comment-20704</link>
		<dc:creator>Marius Gedminas</dc:creator>
		<pubDate>Wed, 22 Apr 2009 23:26:18 +0000</pubDate>
		<guid isPermaLink="false">http://eikke.com/?p=103#comment-20704</guid>
		<description>Python rules.

In a rather similar way, Python lets you compare more than two values at once, e.g. 1 &lt; x &lt; 100. Most other programming languages would require you to split that into multiple comparisons combined with boolean operators.</description>
		<content:encoded><![CDATA[<p>Python rules.</p>
<p>In a rather similar way, Python lets you compare more than two values at once, e.g. 1 &lt; x &lt; 100. Most other programming languages would require you to split that into multiple comparisons combined with boolean operators.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Kristof Provost</title>
		<link>http://eikke.com/python-value-swap/comment-page-1/#comment-20699</link>
		<dc:creator>Kristof Provost</dc:creator>
		<pubDate>Wed, 22 Apr 2009 20:09:34 +0000</pubDate>
		<guid isPermaLink="false">http://eikke.com/?p=103#comment-20699</guid>
		<description>In case anyone cares Perl has a very similar construct:
($a, $b) = ($b, $a);</description>
		<content:encoded><![CDATA[<p>In case anyone cares Perl has a very similar construct:<br />
($a, $b) = ($b, $a);</p>
]]></content:encoded>
	</item>
</channel>
</rss>
