Python: find smallest values in nested dict
Python 2.7
This is a Python variation : get the key with the smallest value from the BUT dictionary multiple minimum values
I have a dictionary that looks like this:
dates = {
'first record': {
'first date': '1985',
'last date': '2000',
},
'second record': {
'first date': '1985',
'last date': '2012',
},
'third record': {
'first date': '1985',
'last date': '2000',
},
'fourth record': {
'first date': '2000',
'last date': '2014',
}
}
I am trying to extract the key of the oldest record (s) where oldest means earliest first date and earliest date. The above example returns "first record" and "third record".
I'm having a hard time figuring out how to implement a solution using the itervalues / iteritems approach described in answers to similar (but less complex) questions. Can anyone suggest some guidance?
source to share
Since you just want the keys:
mn_year = min((int(d['first date']), int(d['last date'])) for d in dates.values())
print(mn_year)
print([k for k in dates
if (int(dates[k]['first date']), int(dates[k]['last date'])) == mn_year])
(1985, 2000)
['third record', 'first record']
If the values are not related, you need to calculate min separately ie:
dates = {
'first record': {
'first date': '1984',
'last date': '2001',
},
'second record': {
'first date': '1985',
'last date': '2012',
},
'third record': {
'first date': '1985',
'last date': '2000',
},
'fourth record': {
'first date': '2000',
'last date': '2014',
}
}
mn_first = min((int(d['first date'])) for d in dates.values())
mn_last = min((int(d['last date'])) for d in dates.values())
print([k for k,v in dates.iteritems()
if int(v['first date']) == mn_first or int(v['last date']) == mn_last])
returns ['third record', 'first record']
as opposed ['first record']
to using the first code.
Getting the minimum number of tuples will not get the min of each key other than the minimum number of paired tuples, so any unique first date
will not necessarily be paired with a minimum last date
unless there is a min last date
in the same dict.
Instead of looping twice to get min, we can get both values with a loop:
mn_first, mn_last = float("inf"),float("inf")
for d in dates.values():
f, l = int(d['first date']),int(d['last date'])
if f < mn_first:
mn_first = f
if l < mn_last:
mn_last = l
print([k for k,v in dates.iteritems()
if int(v['first date']) == mn_first or int(v['last date']) == mn_last])
source to share