Just identify the appropriate key function. You want int(hour) , int(minute) and 'PM' to sort lexicographically higher than "AM" , but you should consider it first. In addition, you need to take the module for 12 hours, so that 12 will sort less than other numbers within pm / am :
In [39]: timeList = [('4', '12', 'PM'), ('8', '23', 'PM'), ('4', '03', 'AM'), ('1', '34', 'AM'), ...: ('12', '48', 'PM'), ('4', '13', 'AM'), ('11', '09', 'AM'), ('3', '12', 'PM'), ...: ('4', '10', 'PM')] In [40]: def key(t): ...: h, m, z = t ...: return z, int(h)%12, int(m) ...: In [41]: max(timeList,key=key) Out[41]: ('8', '23', 'PM')
But the most important thing is to actually use datetime.time objects, instead of pretending to be a tuple of strings, is a good way to store time.
So something like:
In [49]: def to_time(t): ...: h, m, z = t ...: h, m = int(h)%12, int(m) ...: if z == "PM": ...: h += 12 ...: return datetime.time(h, m) ...: In [50]: real_time_list = list(map(to_time, timeList)) In [51]: real_time_list Out[51]: [datetime.time(16, 12), datetime.time(20, 23), datetime.time(4, 3), datetime.time(1, 34), datetime.time(12, 48), datetime.time(4, 13), datetime.time(11, 9), datetime.time(15, 12), datetime.time(16, 10)] In [52]: list(map(str, real_time_list)) Out[52]: ['16:12:00', '20:23:00', '04:03:00', '01:34:00', '12:48:00', '04:13:00', '11:09:00', '15:12:00', '16:10:00']
Notice now max "just works":
In [54]: t = max(real_time_list) In [55]: print(t) 20:23:00
And if you need a nice line to print, just do the formatting at this point:
In [56]: print(t.strftime("%I:%M %p")) 08:23 PM