Need help with getting Key, Value out of dicts in lists
Peter Otten
__peter__ at web.de
Sun Apr 9 04:15:51 EDT 2017
Kenton Brede wrote:
> This is an example of the data I'm working with. The key/value pairs may
> come in any order. There are some keys like the 'Resource_group_id' key
> and the 'Name' key which will always be present, but other lists may have
> unique keys.
>
> alist = [[{u'Value': 'shibboleth-prd', u'Key': 'Name'}, {u'Value': 'kvmu',
> u'Key': 'Billing'},
> {u'Value': '20179204-181622543367489', u'Key':
> 'Resource_group_id'}],
> [{u'Value': '20172857-152037106154311', u'Key':
> 'Resource_group_id'},
> {u'Value': 'shibboleth-tst', u'Key': 'Name'}]]
>
> What I want to do is something along the lines of:
>
> for a in alist:
> if a['Resource_group_id'] == '01234829-2041523815431':
> print the Value of 'Name'
> print the Value of 'Billing'
>
> I've found I can do the following, to print the value of 'Name' but that
> only works if the 'Resource_group_id' key is the first key in the list and
> the 'Name' key is in the second slot. If each list contained the same
> keys, I could probably sort the keys and use [num] to pull back values,
> but they don't.
>
> for a in alist:
> if a[0]['Key'] == 'Resource_group_id' and a[0]['Value'] ==
> '20172857-152037106154311':
> print a[1]['Value']
>
> There has to be a way to do this but I've been pounding away at this for
> hours. Any help appreciated. I'm new to Python and not a programmer, so
> go easy on me. :)
The easiest approach is to convert the inner list of dicts into one
dictionary. Here's a way that ensures that duplicates are not overwritten
silently:
def to_dict(pairs):
result = {}
for pair in pairs:
key = pair["Key"]
value = pair["Value"]
if key in result:
raise ValueError("Duplicate key {!r}".format(key))
result[key] = value
return result
Example:
>>> to_dict([{"Key": "foo", "Value": "bar"}, {"Key": "one", "Value":
"two"}])
{'foo': 'bar', 'one': 'two'}
Now you can convert your data:
blist = [to_dict(pairs) for pairs in alist]
Then the rest of the code becomes straight-forward:
# linear lookup, you have to go through the whole list
# to find the matching items
for b in blist:
if b["Resource_group_id"] == '20179204-181622543367489':
print b["Name"]
print b["Billing"]
If you are planning to do more than a few lookups and the lookup is always
by resource group ID you can use a dict as the outer data structure, too:
from collections import defaultdict
# map ressource-group-ID to list of matching dicts
bdict = defaultdict(list)
for pairs in alist:
d = to_dict(pairs)
bdict[d["Resource_group_id"]].append(d)
# constant-time lookup of a list containing all matching items
for b in bdict["20179204-181622543367489"]:
print b["Name"]
print b["Billing"]
More information about the Python-list
mailing list