4

Python 2.7

This is a variation on Python: get key with the least value from a dictionary BUT 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 retrieve the key(s) of the oldest record(s), where oldest means the earliest first date and earliest last date. In the above example, 'first record' and 'third record' would both be returned.

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. Could anyone offer some guidance?

Community
  • 1
  • 1
AutomaticStatic
  • 1,661
  • 3
  • 21
  • 42
  • It might be more beneficial to implement a class and override comparative magic methods, then sort them. – C.B. May 07 '15 at 20:23

1 Answers1

3

As 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 the min separately i.e:

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 to ['first record'] using the first code.

Getting a min of tuples will not get the min of each key but the min of the paired up tuple so any unique first date will not necessarily get paired with the minimum last date unless the min last date happens to be in the same dict.

Instead of looping twice to get the min we can get both at the same using 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])
Padraic Cunningham
  • 176,452
  • 29
  • 245
  • 321