Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #69549 > unrolled thread
| Started by | Roy Smith <roy@panix.com> |
|---|---|
| First post | 2014-04-02 13:58 -0400 |
| Last post | 2014-04-03 01:00 -0600 |
| Articles | 8 — 6 participants |
Back to article view | Back to comp.lang.python
Retrieve item deep in dict tree? Roy Smith <roy@panix.com> - 2014-04-02 13:58 -0400
Re: Retrieve item deep in dict tree? John Gordon <gordon@panix.com> - 2014-04-02 18:03 +0000
Re: Retrieve item deep in dict tree? Steven D'Aprano <steve@pearwood.info> - 2014-04-02 20:18 +0000
Re: Retrieve item deep in dict tree? Ethan Furman <ethan@stoneleaf.us> - 2014-04-02 13:25 -0700
Re: Retrieve item deep in dict tree? Rustom Mody <rustompmody@gmail.com> - 2014-04-02 19:41 -0700
Re: Retrieve item deep in dict tree? Rustom Mody <rustompmody@gmail.com> - 2014-04-02 21:15 -0700
Re: Retrieve item deep in dict tree? Steven D'Aprano <steve@pearwood.info> - 2014-04-03 05:29 +0000
Re: Retrieve item deep in dict tree? Ian Kelly <ian.g.kelly@gmail.com> - 2014-04-03 01:00 -0600
| From | Roy Smith <roy@panix.com> |
|---|---|
| Date | 2014-04-02 13:58 -0400 |
| Subject | Retrieve item deep in dict tree? |
| Message-ID | <mailman.8818.1396461529.18130.python-list@python.org> |
I have a big hairy data structure which is a tree of nested dicts. I have a sequence of strings which represents a path through the tree. Different leaves in the tree will be at different depths (which range from 1 to about 4 or 5 at most). I want to get the value stored at that path. Thus, if keys = ['foo', 'bar', 'baz'] I want to retrieve tree['foo']['bar']['baz']. Is there some idiomatic, non-cryptic way to write that as a one-liner? I'm using Python 2.7. --- Roy Smith roy@panix.com
[toc] | [next] | [standalone]
| From | John Gordon <gordon@panix.com> |
|---|---|
| Date | 2014-04-02 18:03 +0000 |
| Message-ID | <lhhjcr$e5s$1@reader1.panix.com> |
| In reply to | #69549 |
In <mailman.8818.1396461529.18130.python-list@python.org> Roy Smith <roy@panix.com> writes:
> I have a big hairy data structure which is a tree of nested dicts. I =
> have a sequence of strings which represents a path through the tree. =
> Different leaves in the tree will be at different depths (which range =
> from 1 to about 4 or 5 at most). I want to get the value stored at that =
> path. Thus, if
> keys =3D ['foo', 'bar', 'baz']
> I want to retrieve tree['foo']['bar']['baz'].
> Is there some idiomatic, non-cryptic way to write that as a one-liner?
> I'm using Python 2.7.
How about three lines?
subtree = tree
for key in keys:
subtree = subtree.get(key)
--
John Gordon Imagine what it must be like for a real medical doctor to
gordon@panix.com watch 'House', or a real serial killer to watch 'Dexter'.
[toc] | [prev] | [next] | [standalone]
| From | Steven D'Aprano <steve@pearwood.info> |
|---|---|
| Date | 2014-04-02 20:18 +0000 |
| Message-ID | <533c70a5$0$2909$c3e8da3$76491128@news.astraweb.com> |
| In reply to | #69549 |
On Wed, 02 Apr 2014 13:58:16 -0400, Roy Smith wrote:
> I have a big hairy data structure which is a tree of nested dicts. I
> have a sequence of strings which represents a path through the tree.
> Different leaves in the tree will be at different depths (which range
> from 1 to about 4 or 5 at most). I want to get the value stored at that
> path. Thus, if
>
> keys = ['foo', 'bar', 'baz']
>
> I want to retrieve tree['foo']['bar']['baz'].
>
> Is there some idiomatic, non-cryptic way to write that as a one-liner?
Er, idiomatic one liner? No, not really. But a helper function makes
nearly anything into a one-liner:
def traverse(tree, *keys):
t = tree
for k in keys:
t = t[k]
return t
# one-liner
leaf = traverse(tree, *list_of_keys)
--
Steven
[toc] | [prev] | [next] | [standalone]
| From | Ethan Furman <ethan@stoneleaf.us> |
|---|---|
| Date | 2014-04-02 13:25 -0700 |
| Message-ID | <mailman.8821.1396471817.18130.python-list@python.org> |
| In reply to | #69554 |
On 04/02/2014 01:18 PM, Steven D'Aprano wrote: > On Wed, 02 Apr 2014 13:58:16 -0400, Roy Smith wrote: > >> I have a big hairy data structure which is a tree of nested dicts. I >> have a sequence of strings which represents a path through the tree. >> Different leaves in the tree will be at different depths (which range >> from 1 to about 4 or 5 at most). I want to get the value stored at that >> path. Thus, if >> >> keys = ['foo', 'bar', 'baz'] >> >> I want to retrieve tree['foo']['bar']['baz']. >> >> Is there some idiomatic, non-cryptic way to write that as a one-liner? > > Er, idiomatic one liner? No, not really. But a helper function makes > nearly anything into a one-liner: > > def traverse(tree, *keys): > t = tree > for k in keys: > t = t[k] > return t > > # one-liner > leaf = traverse(tree, *list_of_keys) +1 Short, simple -- good Python. :) -- ~Ethan~
[toc] | [prev] | [next] | [standalone]
| From | Rustom Mody <rustompmody@gmail.com> |
|---|---|
| Date | 2014-04-02 19:41 -0700 |
| Message-ID | <5d184a3a-c8d2-40d6-8055-7f7d1eb96127@googlegroups.com> |
| In reply to | #69549 |
On Wednesday, April 2, 2014 11:28:16 PM UTC+5:30, Roy Smith wrote:
> I have a big hairy data structure which is a tree of nested dicts. I have a sequence of strings which represents a path through the tree. Different leaves in the tree will be at different depths (which range from 1 to about 4 or 5 at most). I want to get the value stored at that path. Thus, if
> keys = ['foo', 'bar', 'baz']
> I want to retrieve tree['foo']['bar']['baz'].
> Is there some idiomatic, non-cryptic way to write that as a one-liner?
> I'm using Python 2.7.
What you are asking for is probably:
>>> reduce((lambda tr, att: tr[att]), ['a','b','c'], nested)
'Hiii!!'
>>>
I used a nested thus
>>> nested = {'a':{'b':{'c':"Hiii!!"}}}
But what you are REALLY looking for is what Steven/Gordon gave <wink>
In order to see more visibly that those whiles are just reduces
you may want to rewrite as:
>>> reduce((lambda tr, att: str(tr) + "[" + str(att) + "]"), ['a','b','c'], "nested")
'nested[a][b][c]'
IOW the 'theorem' I am using is that
reduce(op, id, l)
is short for
while l:
id, l = op(id, l[0]), l[1:]
return id
[toc] | [prev] | [next] | [standalone]
| From | Rustom Mody <rustompmody@gmail.com> |
|---|---|
| Date | 2014-04-02 21:15 -0700 |
| Message-ID | <141eca25-744b-47c0-8b2b-d8d08f8b27ef@googlegroups.com> |
| In reply to | #69566 |
On Thursday, April 3, 2014 8:11:33 AM UTC+5:30, Rustom Mody wrote: > On Wednesday, April 2, 2014 11:28:16 PM UTC+5:30, Roy Smith wrote: > > I have a big hairy data structure which is a tree of nested dicts. I have a sequence of strings which represents a path through the tree. Different leaves in the tree will be at different depths (which range from 1 to about 4 or 5 at most). I want to get the value stored at that path. Thus, if > > keys = ['foo', 'bar', 'baz'] > > I want to retrieve tree['foo']['bar']['baz']. > > Is there some idiomatic, non-cryptic way to write that as a one-liner? > > I'm using Python 2.7. > What you are asking for is probably: > >>> reduce((lambda tr, att: tr[att]), ['a','b','c'], nested) > 'Hiii!!' Shorter version: >>> reduce(dict.get, ['a','b','c'], nested) 'Hiii!!'
[toc] | [prev] | [next] | [standalone]
| From | Steven D'Aprano <steve@pearwood.info> |
|---|---|
| Date | 2014-04-03 05:29 +0000 |
| Message-ID | <533cf1cb$0$2909$c3e8da3$76491128@news.astraweb.com> |
| In reply to | #69568 |
On Wed, 02 Apr 2014 21:15:23 -0700, Rustom Mody wrote: >>>> reduce(dict.get, ['a','b','c'], nested) > 'Hiii!!' Nice! -- Steven
[toc] | [prev] | [next] | [standalone]
| From | Ian Kelly <ian.g.kelly@gmail.com> |
|---|---|
| Date | 2014-04-03 01:00 -0600 |
| Message-ID | <mailman.8827.1396508455.18130.python-list@python.org> |
| In reply to | #69568 |
On Wed, Apr 2, 2014 at 10:15 PM, Rustom Mody <rustompmody@gmail.com> wrote: > On Thursday, April 3, 2014 8:11:33 AM UTC+5:30, Rustom Mody wrote: >> On Wednesday, April 2, 2014 11:28:16 PM UTC+5:30, Roy Smith wrote: >> > I have a big hairy data structure which is a tree of nested dicts. I have a sequence of strings which represents a path through the tree. Different leaves in the tree will be at different depths (which range from 1 to about 4 or 5 at most). I want to get the value stored at that path. Thus, if > >> > keys = ['foo', 'bar', 'baz'] > >> > I want to retrieve tree['foo']['bar']['baz']. > >> > Is there some idiomatic, non-cryptic way to write that as a one-liner? > >> > I'm using Python 2.7. > >> What you are asking for is probably: > >> >>> reduce((lambda tr, att: tr[att]), ['a','b','c'], nested) >> 'Hiii!!' > > Shorter version: > >>>> reduce(dict.get, ['a','b','c'], nested) > 'Hiii!!' That breaks if the dicts are ever replaced with an alternate mapping implementation (or a dict subclass that overrides the get method), and incorrectly returns None instead of raising KeyError if the last key in the sequence does not exist (and if any of the other keys don't exist, you'll get a TypeError instead of a KeyError). This is more robust: import operator reduce(operator.getitem, ['a', 'b', 'c'], nested)
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.python
csiph-web