简体   繁体   中英

Looping through a dictionary to get values

I have a dict I am working with and I would like to loop through it and pull the value(s) for 'network' under both 'process-id' and process-id-vrf'. I cant seem to get it to pull both, only one or the other. Can someone give me some advice on how to make this work. Here is the output from ospf_protocol.items() so you can see the structure.

dict_items([('process-id', [{'id': 2, 'area': [{'area-id': 0, 'authentication': {'message-digest': [None]}}], 'network': [{'ip': '192.168.200.0', 'wildcard': '0.0.0.255', 'area': 0}]}]), ('process-id-vrf', [{'id': 1, 'vrf': 'army', 'area': [{'area-id': 0, 'authentication': {'message-digest': [None]}}], 'network': [{'ip': '192.1.1.1', 'wildcard': '0.0.0.0', 'area': 0}, {'ip': '192.168.100.1', 'wildcard': '0.0.0.0', 'area': 0}], 'router-id': '192.1.1.1'}])])



    for network_statement in ospf_protocol['process-id'] or ospf_protocol['process-id-vrf']:
        for ospf_network in network_statement['network']:
            ospf_interface = ospf_network['ip']
            ospf_wildcard = ospf_network['wildcard']
            # determine netmask and network address for valid ospf enabled interfaces
            wildcard_to_mask = str(ipaddress.ip_network(ospf_interface+'/'+ospf_wildcard, strict=False).netmask)
            if wildcard_to_mask == '0.0.0.0':
                wildcard_to_mask = '255.255.255.255'
                ospf_int_range = ipaddress.ip_interface(ospf_interface+'/'+wildcard_to_mask)
            else:
                ospf_int_range = ipaddress.ip_interface(ospf_interface+'/'+wildcard_to_mask)

Ok, first things first:

1/ Python objects all have a truth value in a boolean context. For the builtin types, numerical zero, empty containers and the empty string are all false.

2/ the logical operators 'and' and 'or' don't return a boolean value, but for 'and' the last operand if both are true else the second operand, for 'or' the first operand that is not false, else the last operand.

So this:

in ospf_protocol['process-id'] or ospf_protocol['process-id-vrf']

doesn't do what you expect - it first evaluates ospf_protocol['process-id'] or ospf_protocol['process-id-vrf'] , and return the first of those object that is not empty (or the last one if both are empty).

Now your code snippet isn't a proper minimal reproducible example and we don't know for sure what types are ospf_protocol['process-id'] and ospf_protocol['process-id-vrf'] - but assuming they are lists of dicts, you can

1/ concatenate them:

all_processes = ospf_protocol['process-id'] +  ospf_protocol['process-id-vrf']
for item in all_processes:
    print(item)

2/ use itertools.chain() to avoid building a new list (only of interest if those lists are huge):

import itertools
all_protocols = itertools.chain(ospf_protocol['process-id'],  ospf_protocol['process-id-vrf']) 
for item in all_protocols:
    print(item)

3/ or quite simply add a first for loop iterating over a tuple made of both ie:

for processe in (ospf_protocol['process-id'],  ospf_protocol['process-id-vrf']):
    for item in processes:
        print(item)

I can't of course garantee the result since, well, I don't really know for sure what your data look like, but you can't put the blame on me for this;-)

If I correctly understand what you are trying to you do not need to loop over the dict. More like ospf_protocol['process-id']['network'] and ospf_protocol['process-id-vrf']['network']

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM