<?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: Memoization in Python: easier than what it should be</title>
	<atom:link href="http://pko.ch/2008/08/22/memoization-in-python-easier-than-what-it-should-be/feed/" rel="self" type="application/rss+xml" />
	<link>http://pko.ch/2008/08/22/memoization-in-python-easier-than-what-it-should-be/</link>
	<description>Reflections about reflection</description>
	<lastBuildDate>Sun, 29 Jan 2012 23:25:17 +0000</lastBuildDate>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
	<item>
		<title>By: pkoch</title>
		<link>http://pko.ch/2008/08/22/memoization-in-python-easier-than-what-it-should-be/comment-page-1/#comment-45</link>
		<dc:creator>pkoch</dc:creator>
		<pubDate>Mon, 25 Aug 2008 01:16:50 +0000</pubDate>
		<guid isPermaLink="false">http://pko.ch/?p=15#comment-45</guid>
		<description>Illustrative example:
&lt;code&gt;&lt;pre&gt;
@memoize
def prt(*args,**kwargs):
    print &quot;Calculated!&quot;
    return (args,kwargs)

a = [1,2,3]
print prt(a,one=10, c=&#039;cee&#039;, d2=&#039;two&#039;)

a.append(1)
print prt(a, one=10, c=&#039;cee&#039;, d2=&#039;two&#039;)
print prt(a, one=10, d2=&#039;two&#039;, c=&#039;cee&#039;)

a.pop()
print prt(a, c=&#039;cee&#039;,one=10, d2=&#039;two&#039;)
&lt;/pre&gt;
&lt;/code&gt;
</description>
		<content:encoded><![CDATA[<p>Illustrative example:<br />
<code>
<pre>
@memoize
def prt(*args,**kwargs):
    print "Calculated!"
    return (args,kwargs)

a = [1,2,3]
print prt(a,one=10, c='cee', d2='two')

a.append(1)
print prt(a, one=10, c='cee', d2='two')
print prt(a, one=10, d2='two', c='cee')

a.pop()
print prt(a, c='cee',one=10, d2='two')
</pre>
<p></code></p>
]]></content:encoded>
	</item>
	<item>
		<title>By: pkoch</title>
		<link>http://pko.ch/2008/08/22/memoization-in-python-easier-than-what-it-should-be/comment-page-1/#comment-44</link>
		<dc:creator>pkoch</dc:creator>
		<pubDate>Mon, 25 Aug 2008 00:05:31 +0000</pubDate>
		<guid isPermaLink="false">http://pko.ch/?p=15#comment-44</guid>
		<description>I&#039;ve updated my post to reflect many of the improvements presented on reddit comments.

Thank you, all! =)</description>
		<content:encoded><![CDATA[<p>I&#8217;ve updated my post to reflect many of the improvements presented on reddit comments.</p>
<p>Thank you, all! =)</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: pkoch</title>
		<link>http://pko.ch/2008/08/22/memoization-in-python-easier-than-what-it-should-be/comment-page-1/#comment-40</link>
		<dc:creator>pkoch</dc:creator>
		<pubDate>Sat, 23 Aug 2008 01:49:20 +0000</pubDate>
		<guid isPermaLink="false">http://pko.ch/?p=15#comment-40</guid>
		<description>John (et al.): Bug fixed! Thank you!

Jonas Gorauskas: I came up with this memoization code to cache some DB calls, as mentioned in the post. I had to run through 40k+ rows in Excel and do some auxiliary queries to construct insert statements. Those auxiliary queries would always return the same result for the same arguments. Memoization just popped into my mind.</description>
		<content:encoded><![CDATA[<p>John (et al.): Bug fixed! Thank you!</p>
<p>Jonas Gorauskas: I came up with this memoization code to cache some DB calls, as mentioned in the post. I had to run through 40k+ rows in Excel and do some auxiliary queries to construct insert statements. Those auxiliary queries would always return the same result for the same arguments. Memoization just popped into my mind.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Nobody In Particular</title>
		<link>http://pko.ch/2008/08/22/memoization-in-python-easier-than-what-it-should-be/comment-page-1/#comment-38</link>
		<dc:creator>Nobody In Particular</dc:creator>
		<pubDate>Fri, 22 Aug 2008 21:44:14 +0000</pubDate>
		<guid isPermaLink="false">http://pko.ch/?p=15#comment-38</guid>
		<description>list(kwargs.iteritems()).sort()
does not return a list. Instead .sort() sorts the list in place and returns None.</description>
		<content:encoded><![CDATA[<p>list(kwargs.iteritems()).sort()<br />
does not return a list. Instead .sort() sorts the list in place and returns None.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Andrew</title>
		<link>http://pko.ch/2008/08/22/memoization-in-python-easier-than-what-it-should-be/comment-page-1/#comment-37</link>
		<dc:creator>Andrew</dc:creator>
		<pubDate>Fri, 22 Aug 2008 20:03:28 +0000</pubDate>
		<guid isPermaLink="false">http://pko.ch/?p=15#comment-37</guid>
		<description>Isn&#039;t list(kwargs.iteritems()).sort() going to have a value of None ?</description>
		<content:encoded><![CDATA[<p>Isn&#8217;t list(kwargs.iteritems()).sort() going to have a value of None ?</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Jonas Gorauskas</title>
		<link>http://pko.ch/2008/08/22/memoization-in-python-easier-than-what-it-should-be/comment-page-1/#comment-35</link>
		<dc:creator>Jonas Gorauskas</dc:creator>
		<pubDate>Fri, 22 Aug 2008 19:36:43 +0000</pubDate>
		<guid isPermaLink="false">http://pko.ch/?p=15#comment-35</guid>
		<description>I am new to python and in general very interested in how the concept of memoization applies to parsers and other areas. Could you provide a working example of the function above for context? Thanks in advance!</description>
		<content:encoded><![CDATA[<p>I am new to python and in general very interested in how the concept of memoization applies to parsers and other areas. Could you provide a working example of the function above for context? Thanks in advance!</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Peter Jones</title>
		<link>http://pko.ch/2008/08/22/memoization-in-python-easier-than-what-it-should-be/comment-page-1/#comment-34</link>
		<dc:creator>Peter Jones</dc:creator>
		<pubDate>Fri, 22 Aug 2008 18:52:07 +0000</pubDate>
		<guid isPermaLink="false">http://pko.ch/?p=15#comment-34</guid>
		<description>I went ahead and ran this out of curiosity as soon as I got my hands on a Python interpreter and it does indeed work recursively. The subtlety is that using memoize as a decorator redefines what the function refers to, so the recursive calls are indeed to the memoized version. Disregard my previous comment; your version is ten times more elegant than mine!</description>
		<content:encoded><![CDATA[<p>I went ahead and ran this out of curiosity as soon as I got my hands on a Python interpreter and it does indeed work recursively. The subtlety is that using memoize as a decorator redefines what the function refers to, so the recursive calls are indeed to the memoized version. Disregard my previous comment; your version is ten times more elegant than mine!</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: John</title>
		<link>http://pko.ch/2008/08/22/memoization-in-python-easier-than-what-it-should-be/comment-page-1/#comment-33</link>
		<dc:creator>John</dc:creator>
		<pubDate>Fri, 22 Aug 2008 18:13:41 +0000</pubDate>
		<guid isPermaLink="false">http://pko.ch/?p=15#comment-33</guid>
		<description>There is a bug on the 4th line:
&gt;&gt;&gt; print list.sort.__doc__
L.sort(cmp=None, key=None, reverse=False) -- stable sort *IN PLACE*;
cmp(x, y) -&gt; -1, 0, 1

list.sort sorts in place, so the second item in your haxh tuple will always be None. Fix it by changing that line to:
haxh = tuple([args,sorted(kwargs.iteritems())])

sorted will return an iterator (which when put in to the tuple() is changed in to a list)

&gt;&gt;&gt; args = (1,2,3,)
&gt;&gt;&gt; kwargs={&#039;a&#039;:5,&#039;b&#039;:6,&#039;aa&#039;:9}
&gt;&gt;&gt; tuple([args,sorted(kwargs.iteritems())])
((1, 2, 3), [(&#039;a&#039;, 5), (&#039;aa&#039;, 9), (&#039;b&#039;, 6)])</description>
		<content:encoded><![CDATA[<p>There is a bug on the 4th line:<br />
&gt;&gt;&gt; print list.sort.__doc__<br />
L.sort(cmp=None, key=None, reverse=False) &#8212; stable sort *IN PLACE*;<br />
cmp(x, y) -&gt; -1, 0, 1</p>
<p>list.sort sorts in place, so the second item in your haxh tuple will always be None. Fix it by changing that line to:<br />
haxh = tuple([args,sorted(kwargs.iteritems())])</p>
<p>sorted will return an iterator (which when put in to the tuple() is changed in to a list)</p>
<p>&gt;&gt;&gt; args = (1,2,3,)<br />
&gt;&gt;&gt; kwargs={&#8216;a&#8217;:5,&#8217;b':6,&#8217;aa&#8217;:9}<br />
&gt;&gt;&gt; tuple([args,sorted(kwargs.iteritems())])<br />
((1, 2, 3), [('a', 5), ('aa', 9), ('b', 6)])</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Peter Jones</title>
		<link>http://pko.ch/2008/08/22/memoization-in-python-easier-than-what-it-should-be/comment-page-1/#comment-32</link>
		<dc:creator>Peter Jones</dc:creator>
		<pubDate>Fri, 22 Aug 2008 17:57:46 +0000</pubDate>
		<guid isPermaLink="false">http://pko.ch/?p=15#comment-32</guid>
		<description>Very nice. This is almost a mirror image of the memoize function I wrote a few days ago, except I think yours is a bit more robust (mine has no kwargs support, for example).

Where mine shines is with recursive functions. With my first effort, if I tried to memoize the fibonacci function, it would calculate fib(n) the inefficient way and take a million years, then memoize the topmost result and return it. Unfortunately, memoizing a recursive function in this way is impossible, since the function body contains a reference to the non-memoized function.

My solution (which is not exactly great) required a change to the type of input that memoize takes. This is hard to explain and would certainly have been beyond my understanding a week ago so I&#039;ll let my mediocre code speak for me: http://pcj600.googlepages.com/memoize.py

As you can see, the function fibonacci_constructor MAKES the fibonacci function USING a function passed as a parameter for its recursive calls. This way, memoize can step in and tell the function to do recursion using a different function - namely, the memoized version.

It&#039;s a bit ugly and fails to opaque its functionality since it demands a second order function that you&#039;d never write normally. What would be really nice is if we could do a find + replace on the function body, replacing all references to itself with references to the memoized version, so that there&#039;d be no need to pass in the recursive function as a parameter. I bet this is possible with Lisp macros, but I&#039;m still a beginner with Lisp ...</description>
		<content:encoded><![CDATA[<p>Very nice. This is almost a mirror image of the memoize function I wrote a few days ago, except I think yours is a bit more robust (mine has no kwargs support, for example).</p>
<p>Where mine shines is with recursive functions. With my first effort, if I tried to memoize the fibonacci function, it would calculate fib(n) the inefficient way and take a million years, then memoize the topmost result and return it. Unfortunately, memoizing a recursive function in this way is impossible, since the function body contains a reference to the non-memoized function.</p>
<p>My solution (which is not exactly great) required a change to the type of input that memoize takes. This is hard to explain and would certainly have been beyond my understanding a week ago so I&#8217;ll let my mediocre code speak for me: <a href="http://pcj600.googlepages.com/memoize.py" rel="nofollow">http://pcj600.googlepages.com/memoize.py</a></p>
<p>As you can see, the function fibonacci_constructor MAKES the fibonacci function USING a function passed as a parameter for its recursive calls. This way, memoize can step in and tell the function to do recursion using a different function &#8211; namely, the memoized version.</p>
<p>It&#8217;s a bit ugly and fails to opaque its functionality since it demands a second order function that you&#8217;d never write normally. What would be really nice is if we could do a find + replace on the function body, replacing all references to itself with references to the memoized version, so that there&#8217;d be no need to pass in the recursive function as a parameter. I bet this is possible with Lisp macros, but I&#8217;m still a beginner with Lisp &#8230;</p>
]]></content:encoded>
	</item>
</channel>
</rss>

