Chris's Wiki :: blog/python/AccumulatorSetdefault Commentshttps://utcc.utoronto.ca/~cks/space/blog/python/AccumulatorSetdefault?atomcommentsDWiki2011-06-12T05:14:26ZRecent comments in Chris's Wiki :: blog/python/AccumulatorSetdefault.By Chris Siebenmann on /blog/python/AccumulatorSetdefaulttag:CSpace:blog/python/AccumulatorSetdefault:81943bf1abab3cab2d9dd7a3795038c357b047eaChris Siebenmann<div class="wikitext"><p>More on how cheap <code>[]</code> is is now in <a href="https://utcc.utoronto.ca/~cks/space/blog/python/CheapListDictTupleCreation">CheapListDictTupleCreation</a>.</p>
</div>2011-06-12T05:14:26ZBy Chris Siebenmann on /blog/python/AccumulatorSetdefaulttag:CSpace:blog/python/AccumulatorSetdefault:826f9d550417ecc574bdf4140668cad4a96e0017Chris Siebenmann<div class="wikitext"><p>The difference between the two cases is that construction of new empty
lists and dictionaries is, as I understand it, quite optimized in
CPython and is thus quite cheap and fast. Construction of arbitrary
Python objects is much more expensive.</p>
<p>(Part of the reason that <code>[]</code> and <code>{}</code> can be so cheap is that
they are language primitives.)</p>
</div>2011-06-10T14:54:53ZFrom 62.194.124.13 on /blog/python/AccumulatorSetdefaulttag:CSpace:blog/python/AccumulatorSetdefault:f369efa3c80910ac28b4fccb10cc031e269449d0From 62.194.124.13<div class="wikitext"><p><code>foo.setdefault(bar, [])</code> is equivalent to <code>foo.setdefault(bar, list())</code>, so it it also constructs objects needlessly. Following defaultdict, setdefault should accept a function, so that you can do <code>foo.setdefault(bar, list)</code> or <code>foo.setdefault(bar, lambda: bar / 2 + 1)</code>. -- Andreas</p>
</div>2011-06-10T11:34:28ZFrom 70.17.43.172 on /blog/python/AccumulatorSetdefaulttag:CSpace:blog/python/AccumulatorSetdefault:529a543c21246f0cdffea093afe496fe6fecb02cFrom 70.17.43.172<div class="wikitext"><p>I'll note that ruby has this problem solved easily:</p>
<pre>
irb(main):001:0> h = Hash.new {|h,k|h[k]=[]}
=> {}
irb(main):002:0> h[5] += [4,2,1,"asdf"]
=> [4, 2, 1, "asdf"]
irb(main):003:0> h[2] += [1,2]
=> [1, 2]
irb(main):004:0> h
=> {5=>[4, 2, 1, "asdf"], 2=>[1, 2]}
</pre>
<p>You can even get strangely recursive and make an autohash:</p>
<pre>
irb(main):005:0> a = Hash.new{|h,k| h[k]=Hash.new &h.default_proc}
=> {}
irb(main):006:0> a[2][1]=2
=> 2
irb(main):007:0> a[2][2][3]=4
=> 4
irb(main):008:0> a[3][1][1][1]=1
=> 1
irb(main):009:0> a
=> {2=>{1=>2, 2=>{3=>4}}, 3=>{1=>{1=>{1=>1}}}}
</pre>
<p>Note that the autohash that you can twist around and give ruby is what perl has all the time, by default; this:</p>
<pre>
sub addstuff {
my($h, $k, @a) = @_; # hash, key, stuff-to-add
push @{$h->{$k}}, @a;
}
</pre>
<p>will just do the right thing, and cause array refs to spring into being as necessary.</p>
</div>2009-02-16T02:06:35ZBy Chris Siebenmann on /blog/python/AccumulatorSetdefaulttag:CSpace:blog/python/AccumulatorSetdefault:7e349055c49560c660496b8ed10d6b12c4084d72Chris Siebenmann<div class="wikitext"><p>You're completely right; <code>collections.defaultdict</code> does just this.
I'll have to remember the <a href="http://docs.python.org/library/collections.html">collections module</a> for future usage
in general.</p>
<p>(Most of my large Python programming was several years ago, so a bunch
of my reflexes are still partly back around Python 2.2 or so. Someday I
need to do something moderately big with modern Python, so all of these
neat new things stick in my mind.)</p>
</div>2009-02-13T16:21:53ZFrom 72.136.17.228 on /blog/python/AccumulatorSetdefaulttag:CSpace:blog/python/AccumulatorSetdefault:f013fd8af8c9f035e5ce36ecc259e64b49d71b82From 72.136.17.228<div class="wikitext"><p>I prefer <code>collections.defaultdict</code> myself.</p>
<p>-Jeremy</p>
</div>2009-02-13T07:06:53Z