f.rodrigues
f.rodrigues

Reputation: 3587

Sorting Numericly and by Month name

I have a single function that takes 3 diffrent inputs:

A dict of Days in the following formart:

"Day 2":Something,
"Day 1":Something,
"Day 3":Something,
"Day 5":Something,
"Day 4":Something

A dict of weeks:

"Week 2":Something,
"Week 1":Something,
"Week 4":Something,   
"Week 3":Something,
"Week 5":Something

A dict of months:

"April":Something,
"February":Something,
"March":Something,
"January":Something

Since they are dicts, they come in unordered. I'm manipulating them to present to the user in ordered fashion.

I'm looking for a way to split the sorted() built-in to deal with the three types.

The output should be the keys sorted numercly(days/week) and by month:

"Day 1"
"Day 2"
"Day 3"
"Day 4"
"Day 5"
###
"Week 1"
"Week 2"
"Week 3"
"Week 4"
"Week 5"
###
"January"
"February"
"March"
"April"

I know I can use Ternary Operation:

sorted(input_dict, key=lambda x: int(x.strip("Day ")) if "Day 1" in input_dict else sorted(input_dict, key=lambda x: int(x.strip("Week ")) if "Week 1" in input_dict else sorted...

But it gets quite messy.

I'm looking for how to implement the key function with a already defined function.

Something like:

def my_sort_function():
    # magic goes here

for n in sorted(input_dict, key=my_function):
    pass

Upvotes: 0

Views: 2173

Answers (1)

mgilson
mgilson

Reputation: 309929

so ... Sorting your lists of days/weeks is pretty easy:

def sort_day_week_key(day_week_str):
    return int(day_week_str.split()[-1])

But you want to handle months as well. The obvious solution is a mapping of month names to numbers:

import calendar
_MONTH_MAP = {m.lower(): i for i, m in enumerate(calendar.month_name[1:])}
def sort_month_names_key(m_name):
    return _MONTH_MAP[m_name.lower()]

Now you just want to combine those two functions. This is pretty easy: try one, if it doesn't work use the other:

def sort_the_stuff_key(item):
    try:
        return sort_month_names_key(item)
    except KeyError:
        return sort_day_week_key

def sort_the_stuff(some_iterable):
    return sorted(some_iterable, key=sort_the_stuff_key)

Of course, this sort function will give strange results if your iterable has items from more than one class of string (e.g. days and month names) but it sounds like that won't happen...

Upvotes: 2

Related Questions