Live data from Hacker News

One-line Tree In Python

gist.github.com

21–30 of 38 posts

Re: One-line Tree In Python

#21
Very nice! I've been a bit leery though of defaultdict since it contributed to two different bugs in http://norvig.com/spell-correct.html -- in less than a page of code, by a first-rate programmer, which was read by many thousands of others for years before anyone noticed the second bug. I'm not saying don't use this, I just have a little warning light blink on when I see 'defaultdict' anywhere.

Re: One-line Tree In Python

#22
post #5

This is actually quite elegant and useful. I've done similar things time and time again with code like so: defaultdict(lambda: defaultdict(int)) That allows me to organically build dictionaries (mainly for stat building) using operands like +=.

Also check out collections.Counter.

  x = collections.defaultdict(collections.Counter)
  x['foo']['bar'] += 1
  X['foo'].most_common(10)
 Etc.

Re: One-line Tree In Python

#23

Very nice! I've been a bit leery though of defaultdict since it contributed to two different bugs in http://norvig.com/spell-correct.html -- in less than a page of code, by a first-rate programmer, which was read by many thousands of others for years before anyone noticed the second bug. I'm not saying don't use this, I just have a little warning light blink on when I see 'defaultdict' anywhere.

Both of those errors seem like fundamental category errors. He's using a dictionary construct which effectively makes it so that every key has a value, but then relies on dictionary membership when testing. This happens to work, but it makes little sense. (One could argue that 'foo in bar' should always be True if bar is a defaultdict.) Seems to me like he should have checked the value of the word rather than using 'in'.

You make a good point about this being written by a known intelligent person and seen by many others who didn't see the bugs, but I think it's ultimately a lesson in thinking about semantics rather than behavior. This code relies too much on the behavior of defaultdict rather than just what such a thing means. As long as what it means is kept in mind I think it should be safe.

But that's just, like, my opinion, man.

Re: One-line Tree In Python

#24
post #9

Neat. Works in Ruby, too. def tree; Hash.new {|h, k| h[k] = tree }; end t = tree t[:foo][:bar] = "foobar" # => {:foo=>{:bar=>"foobar"}} Probably more idiomatic to do it as a class, though. class Tree Btw. How do you post nicely formatted code? edit - Thanks!

Here's the ruby one-liner:

  tree = Hash.new { |h, k| h[k] = Hash.new(&h.default_proc) }
(explanation is here: http://matthew.mceachen.us/blog/multi-value-hashes-in-ruby-1...)

Re: One-line Tree In Python

#26
post #15
post #3

In Perl, this is called autovivification: https://en.wikipedia.org/wiki/Autovivification I've wanted something like that in Python at different times... thanks! edit: Ha! The Wiki article even has basically the same code: def hash(): return defaultdict(hash)

> I've wanted something like that in Python at different times... thanks! Python's auto-vivification doens't allow Perl's hap hazard auto-vivification. Perl allows you to say: my $foo = {}; $foo->{'blah'}[0]->{'bar'}++; And after this statement, $foo will refer a hash which has the structure as accessed in the statement. I don't think this can be done for a generalized case in Python. Whether I want is a totally diff…

Why is this haphazard? If you don't want reads to change your data structure shape in a well-defined manner, use 'exists' or make an immutable hash with Hash::Util.

Re: One-line Tree In Python

#27
post #3

In Perl, this is called autovivification: https://en.wikipedia.org/wiki/Autovivification I've wanted something like that in Python at different times... thanks! edit: Ha! The Wiki article even has basically the same code: def hash(): return defaultdict(hash)

I always use http://stackoverflow.com/a/651879/276569

Re: One-line Tree In Python

#28
post #19
post #9

Neat. Works in Ruby, too. def tree; Hash.new {|h, k| h[k] = tree }; end t = tree t[:foo][:bar] = "foobar" # => {:foo=>{:bar=>"foobar"}} Probably more idiomatic to do it as a class, though. class Tree Btw. How do you post nicely formatted code? edit - Thanks!

It works in Ruby because it works in Perl. :) A little known fact is that it works in C++ STL too as long as the objects in your containers have default constructors that make sense. So a map > does what you expect when you try: my_map[12][3] = some_value;

I don't think it's a little known fact that std::map works that way, ie. that operator [] inserts if the key doesn't exist (or at least, it's surely not little known among people using C++?).

Also, I don't think you can have an infinitely expanding std::map in the same way, because all the key/value types have to get rolled into the type signature of the top level map. It's not that hard to write something yourself to achieve it, but it's not going to be the one-liner that it is in Python.

Re: One-line Tree In Python

#29
post #23

Very nice! I've been a bit leery though of defaultdict since it contributed to two different bugs in http://norvig.com/spell-correct.html -- in less than a page of code, by a first-rate programmer, which was read by many thousands of others for years before anyone noticed the second bug. I'm not saying don't use this, I just have a little warning light blink on when I see 'defaultdict' anywhere.

Both of those errors seem like fundamental category errors. He's using a dictionary construct which effectively makes it so that every key has a value, but then relies on dictionary membership when testing. This happens to work, but it makes little sense. (One could argue that 'foo in bar' should always be True if bar is a defaultdict.) Seems to me like he should have checked the value of the word rather than using '…

At some level it was sloppy thinking, yes; most bugs have some obvious-in-retrospect reason they were stupid. You may be right about how to think about this one.

I've seen other defaultdict bugs -- this is just the case with the highest eyeball-count-times-attention product I can point to.

Post reply on HN