4

In the dictionary a:

from datetime import datetime

a = {"ID":3, "CITY":"ATLANTIS", "FOUNDATION":datetime(2014,10,12), "COLLAPSE":datetime(2010,10,12), "REGENERATE":datetime(2011,10,12)}

How would you get the value which has the oldest date in this dictionary (in this case "COLLAPSE":datetime(2010,10,12))? Remember, not all values are of same data type.

Georgy
  • 12,464
  • 7
  • 65
  • 73
alwbtc
  • 28,057
  • 62
  • 134
  • 188
  • You'd still use a key function; in this case you could use `datetime.datetime.max` as fallback if the value is not `datetime` object. – Martijn Pieters Jul 15 '14 at 17:24
  • how would you bind an `if` condition to a max() method in `max(a.iteritems(), key=operator.itemgetter(1))[0]` – alwbtc Jul 15 '14 at 17:30

1 Answers1

5

If you wanted the earliest date, you want to use min(), not max() here; a datetime earlier in time sorts before another that is later.

You'd need to use a custom key callable here, and return datetime.max for any value that is not a datetime object to discount that key:

from datetime import datetime

min(a.iteritems(),
    key=lambda i: i[1] if isinstance(i[1], datetime) else datetime.max)

This returns both the key and the value.

To get just the key, use:

min(a, key=lambda k: a[k] if isinstance(a[k], datetime) else datetime.max)

and for just the value:

min(a.itervalues(),
    key=lambda v: v if isinstance(v, datetime) else datetime.max)

In all cases only the exact syntax to get the value to compare differs.

Demo:

>>> from datetime import datetime
>>> a = {"ID":3, "CITY":"ATLANTIS", "FOUNDATION":datetime(2014,10,12), "COLLAPSE":datetime(2010,10,12), "REGENERATE":datetime(2011,10,12)}
>>> min(a.iteritems(),
...     key=lambda i: i[1] if isinstance(i[1], datetime) else datetime.max)
('COLLAPSE', datetime.datetime(2010, 10, 12, 0, 0))
>>> min(a, key=lambda k: a[k] if isinstance(a[k], datetime) else datetime.max)
'COLLAPSE'
>>> min(a.itervalues(),
...     key=lambda v: v if isinstance(v, datetime) else datetime.max)
datetime.datetime(2010, 10, 12, 0, 0)
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343