Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Complex Sorting of a List

Tags:

python

sorting

I have a list of times from about 8:00am-7:00pm in string format. The am/pm is not specified, and using a 24 hour clock is not an option. I want to sort this list by time, but I'm running into issues after the clock strikes one, since numeric sorting begins at one, despite the fact that 8-12 are actually before that in terms of time. I was thinking I could create a new list of tuples where I ran the times through a function that converted them to a more appropriate number, sorted that, and used the first element of the tuple in the functions that needed that. This seems like it would work, but I fear I may be missing something a lot more elegant and fundamental. Am I?

like image 272
user1427661 Avatar asked Jan 14 '23 12:01

user1427661


2 Answers

Use the key parameter to list.sort() or the sorted() function to provide a value to sort on.

values.sort(key=somefunction)

where somefunction takes one argument (the value to be transformed).

The list will then be sorted based on the return value of the key parameter, but the original values are themselves left untouched.

For your problem, you can then use:

def daytime(val):
    hour, min = map(int, val.split(':'))
    if hour < 8:
        hour += 12
    return hour, min

which would transform 8:01 to (8, 1) and 6:25 to (18, 25), causing .sort() or sorted() to sort 8:01 before 6:25:

>>> sorted(['1:14', '8:01', '12:46', '6:25'], key=daytime)
['8:01', '12:46', '1:14', '6:25']

See the Python Sorting HOWTO for more details and tips (use this Google cache link until wiki.python.org has recovered from the recent security exploit).

like image 51
Martijn Pieters Avatar answered Jan 21 '23 19:01

Martijn Pieters


The function to_minutes converts a string to integer hours and minutes and calculates the number of minutes since 8:00 adding twelve hours to times before 8:00. Then it sorts according to this number of minutes:

def to_minutes(s):
    h,m = map(int, s.split(':'))
    return ((h - 8) % 12) * 60 + m

a = ['1:45', '8:00', '6:15', '12:30']
print sorted(a, key=to_minutes)

prints

['8:00', '12:30', '1:45', '6:15']
like image 27
eumiro Avatar answered Jan 21 '23 18:01

eumiro