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!
One-line Tree In Python
11–20 of 38 posts
Re: One-line Tree In Python
#12Neat. 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!
As for code in comments, see: http://news.ycombinator.com/formatdoc
Re: One-line Tree In Python
#13I would be interest to see this using the __getattr__ rather than __getitem__, so that this is also possible: users = tree() users.harold.username = 'hrldcpr' users.handler.username = 'matthandlersux'
Well, it's as trivial as you say. Just set __getattr__ = __getitem__ in your tree. (Note though that there is/was a small bug(?) in CPython: http://bugs.python.org/issue14658 )
>>> a = tree()
>>> a.__getattr__ = a.__getitem__Re: One-line Tree In Python
#14Earlier quoted context omitted.
Well, it's as trivial as you say. Just set __getattr__ = __getitem__ in your tree. (Note though that there is/was a small bug(?) in CPython: http://bugs.python.org/issue14658 )
Seems like it may take a little more than one line, this errors for me: >>> a = tree() >>> a.__getattr__ = a.__getitem__
It errors for you because it is a defaultdict instance and doesn't allow attribute overwrites.
This should work:
class tree(defaultdict):
def __init__(self): defaultdict.__init__(self, tree)
__getattr__ = defaultdict.__getitem__
__setattr__ = defaultdict.__setitem__
Edit: It doesn't work with the simple assignment because of the mentioned bug. Ofc the fix is trivial. See the code from beagle3.Re: One-line Tree In Python
#15In 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)
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 different question.
Re: One-line Tree In Python
#16 do
local mt = {
__index = function(t, k)
t[k] = tree()
return t[k]
end
}
function tree()
return setmetatable({}, mt)
end
end
t = tree()
t.foo.bar = 'foobar'Re: One-line Tree In Python
#17 type MTree t = Map t (MTree t)
This version works though. data Tree t = Leaf | Node [(t, Tree t)]Re: One-line Tree In Python
#18Neat. 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!
Re: One-line Tree In Python
#19Neat. 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!
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;
Re: One-line Tree In Python
#20Very cool though!