Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Re: Help needed: dynamically pull data from different levels of a dict

13 views
Skip to first unread message

Peter Rubenstein

unread,
Feb 29, 2012, 11:04:46 PM2/29/12
to pytho...@python.org

--Reposting in plan text, apologies--

Hi,

I'd appreciate a bit of help on this problem.  I have some data that I've converted to a dict and I want to pull out individual pieces of it.

Simplified version--
a={'1':'a', '2':'b', '3':{4:'d'}, '5':{'6': {'7': [ {'8':'e'}, {'9':'f'} ] } } }

I'd like to be able to code something like:

data_needed = ['1', '2', '3:4', '5:6:7-8']for val in data_needed:        answer=extract_from(a,val)        print answer

And get:abcde

Problem is I can't figure out what extract_from would look like, such that it would proceed dynamically down to the right level.  I'm open to the possibility that I'm not approaching this the right way.
If it helps, one member of my actual dict quoted below.  So in real life, something likedata_needed=['name','active-defects', 'admin-status:format', 'description', 'traffic-statistics:input-bps']etc.

Thanks in advance,Peter

{ 'ge-0/0/0': {'active-alarms': {'interface-alarms': {'alarm-not-present': ''}},  'active-defects': {'interface-alarms': {'alarm-not-present': ''}},  'admin-status': {'_text': 'up', 'format': 'Enabled'},  'current-physical-address': '00:1f:12:c0:e8:00',  'description': 'INFRA:CROSS:ASH-64CB-1B:GE-0/0/0:',  'hardware-physical-address': '00:1f:12:c0:e8:00',  'if-config-flags': {'iff-snmp-traps': '', 'internal-flags': '0x4000'},  'if-device-flags': {'ifdf-present': '', 'ifdf-running': ''},  'if-flow-control': 'enabled',  'if-media-flags': {'ifmf-none': ''},  'interface-flapped': {'_text': '2010-05-23 18:20:36 UTC (92w3d 02:27 ago)',   'seconds': '55909644'},  'l2pt-error': 'none',  'link-level-type': 'Ethernet',  'local-index': '171',  'logical-interface': {'address-family': [{'address-family-flags': {'ifff-no-redirects': '',      'internal-flags': '0x0'},     'address-family-name': 'inet',     'interface-address': {'ifa-destination': '207.46.43.2/31',      'ifa-flags': {'ifaf-current-preferred': '', 'ifaf-current-primary': ''},      'ifa-local': '207.46.43.2'},     'mtu': '9178'},    {'address-family-flags': {'ifff-mtu-user-conf': '',      'internal-flags': '0x10000000'},     'address-family-name': 'mpls',     'mtu': '9174'},    {'address-family-flags': {'ifff-none': ''},     'address-family-name': 'multiservice',     'mtu': 'Unlimited'}],   'description': 'INFRA:CROSS:ASH-64CB-1B:GE-0/0/0.0:',   'encapsulation': 'ENET2',   'if-config-flags': {'iff-snmp-traps': ''},   'local-index': '67',   'name': 'ge-0/0/0.0',   'snmp-index': '117',   'traffic-statistics': {'input-packets': '46367422526659',    'output-packets': '35670513402384',    'style': 'brief'}},  'loopback': 'disabled',  'mtu': '9192',  'name': 'ge-0/0/0',  'oper-status': 'up',  'physical-interface-cos-information': {'physical-interface-cos-hw-max-queues': '8',   'physical-interface-cos-use-max-queues': '8'},  'snmp-index': '116',  'source-filtering': 'disabled',  'speed': '10Gbps',  'traffic-statistics': {'input-bps': '4104358720',   'input-pps': '1059450',   'output-bps': '2323588888',   'output-pps': '537816',   'style': 'brief'}},}

Chris Rebert

unread,
Feb 29, 2012, 11:43:44 PM2/29/12
to Peter Rubenstein, pytho...@python.org
On Wed, Feb 29, 2012 at 7:56 PM, Peter Rubenstein
<peter.ru...@hotmail.com> wrote:
> Hi,
>
> I'd appreciate a bit of help on this problem.  I have some data that I've
> converted to a dict and I want to pull out individual pieces of it.
>
> Simplified version--
>
> a={'1':'a', '2':'b', '3':{4:'d'}, '5':{'6': {'7': [ {'8':'e'}, {'9':'f'} ] }
> } }
>
> I'd like to be able to code something like:
>
> data_needed = ['1', '2', '3:4', '5:6:7-8']
> for val in data_needed:
>     answer=extract_from(a,val)
>     print answer
>
> And get:
> a
> b
> c

"c" apparently sprung completely out of thin air...

> d
> e
>
> Problem is I can't figure out what extract_from would look like, such that
> it would proceed dynamically down to the right level.  I'm open to the
> possibility that I'm not approaching this the right way.

data_needed = ['1', '2', ('3', '4'), ('5', '6', '7', 0, '8')]

def extract_from(mapping, key_path):
current = mapping
for key in key_path:
current = current[key]
return current


I would perhaps try and restructure the data into something less
generic than nested dicts & lists, e.g. objects. You then might be
able to introduce helper querying methods.
I would also be worried about Law of Demeter violations, but
fortunately your concrete example doesn't reach any deeper than 2
levels.

Cheers,
Chris
--
http://chrisrebert.com

Terry Reedy

unread,
Mar 1, 2012, 12:35:00 AM3/1/12
to pytho...@python.org
On 2/29/2012 11:04 PM, Peter Rubenstein wrote:

> I'd appreciate a bit of help on this problem. I have some data that I've converted to a dict and I want to pull out individual pieces of it.
>
> Simplified version--
> a={'1':'a', '2':'b', '3':{4:'d'}, '5':{'6': {'7': [ {'8':'e'}, {'9':'f'} ] } } }
>
> I'd like to be able to code something like:
>
> data_needed = ['1', '2', '3:4', '5:6:7-8']for val in data_needed: answer=extract_from(a,val) print answer
>
> And get:abcde
>
> Problem is I can't figure out what extract_from would look like, such that it would proceed dynamically down to the right level. I'm open to the possibility that I'm not approaching this the right way.
> If it helps, one member of my actual dict quoted below. So in real life, something likedata_needed=['name','active-defects', 'admin-status:format', 'description', 'traffic-statistics:input-bps']etc.
>
> Thanks in advance,Peter
>
> { 'ge-0/0/0': {'active-alarms': {'interface-alarms': {'alarm-not-present': ''}}, 'active-defects': {'interface-alarms': {'alarm-not-present': ''}}, 'admin-status': {'_text': 'up', 'format': 'Enabled'}, 'current-physical-address': '00:1f:12:c0:e8:00', 'description': 'INFRA:CROSS:ASH-64CB-1B:GE-0/0/0:', 'hardware-physical-address': '00:1f:12:c0:e8:00', 'if-config-flags': {'iff-snmp-traps': '', 'internal-flags': '0x4000'}, 'if-device-flags': {'ifdf-present': '', 'ifdf-running': ''}, 'if-flow-control': 'enabled', 'if-media-flags': {'ifmf-none': ''}, 'interface-flapped': {'_text': '2010-05-23 18:20:36 UTC (92w3d 02:27 ago)', 'seconds': '55909644'}, 'l2pt-error': 'none', 'link-level-type': 'Ethernet', 'local-index': '171', 'logical-interface': {'address-family': [{'address-family-flags': {'ifff-no-redirects': '', 'internal-flags': '0x0'}, 'address-family-name': 'inet', 'interface-address': {'ifa-destination': '207.46.43.2/31', 'ifa-flags': {'ifa
f-current-preferred': '', 'ifaf-current-primary': ''}, 'ifa-local': '207.46.43.2'}, 'mtu': '9178'}, {'address-family-flags': {'ifff-mtu-user-conf': '', 'internal-flags': '0x10000000'}, 'address-family-name': 'mpls', 'mtu': '9174'}, {'address-family-flags': {'ifff-none': ''}, 'address-family-name': 'multiservice', 'mtu': 'Unlimited'}], 'description': 'INFRA:CROSS:ASH-64CB-1B:GE-0/0/0.0:', 'encapsulation': 'ENET2', 'if-config-flags': {'iff-snmp-traps': ''}, 'local-index': '67', 'name': 'ge-0/0/0.0', 'snmp-index': '117', 'traffic-statistics': {'input-packets': '46367422526659', 'output-packets': '35670513402384', 'style': 'brief'}}, 'loopback': 'disabled', 'mtu': '9192', 'name': 'ge-0/0/0', 'oper-status': 'up', 'physical-interface-cos-information': {'physical-interface-cos-hw-max-queues': '8', 'physical-interface-cos-use-max-queues': '8'}, 'snmp-index': '116', 'source-filtering': 'disabled', 'speed': '10Gbps', 't
raffic-statistics': {'input-bps': '4104358720', 'input-pps': '1059450', 'output-bps': '2323588888', 'output-pps': '537816', 'style': 'brief'}},}


--
Terry Jan Reedy

Peter Rubenstein

unread,
Mar 1, 2012, 11:56:16 AM3/1/12
to Chris Rebert, Peter Rubenstein, pytho...@python.org
Thanks, Chris. That's the algorithm I was looking for. And I will be converting most of this data to objects. Thanks again.

-----Original Message-----
From: Chris Rebert [mailto:cl...@rebertia.com]
Sent: Wednesday, February 29, 2012 11:44 PM
Subject: Re: Help needed: dynamically pull data from different levels of a dict

On Wed, Feb 29, 2012 at 7:56 PM, Peter Rubenstein <peter.ru...@hotmail.com> wrote:
> Hi,
>
> I'd appreciate a bit of help on this problem. I have some data that
> I've converted to a dict and I want to pull out individual pieces of it.
>
> Simplified version--
>
> a={'1':'a', '2':'b', '3':{4:'d'}, '5':{'6': {'7': [ {'8':'e'},
> {'9':'f'} ] } } }
>
> I'd like to be able to code something like:
>
> data_needed = ['1', '2', '3:4', '5:6:7-8'] for val in data_needed:
> answer=extract_from(a,val)
> print answer
>
> And get:
> a
> b
> c

"c" apparently sprung completely out of thin air...

> d
> e
>
> Problem is I can't figure out what extract_from would look like, such
> that it would proceed dynamically down to the right level. I'm open
> to the possibility that I'm not approaching this the right way.

0 new messages