0

So, I have a list of strings that are all formatted in Month DayNumber, like

['March 1', 'March 9', 'April 14', 'March 12']

I need to sort the list so all the dates are in the order they would be in a calendar. Any tips? Is there a built-in method that might be able to help me, or should I design a custom sort using a lambda?

1
  • Other than the key argument? Commented Mar 19, 2018 at 17:17

5 Answers 5

1

You may want to review this question: Converting string into datetime

After parsing you could sort by date based on the values obtained from parsing string into datetime objects (which are sortable).

Sign up to request clarification or add additional context in comments.

3 Comments

I had done that, and had the code (sorted(testing, key=lambda x: datetime.datetime.strptime(x, '%m-%Y-%d'))), but it did not work so I went back to the drawing board.
are you sure %Y should have been there? I would just use '%B %d' (where %B is the full month name in the current locale). It worked for me like a charm on the data you provided.
my data was different when I wrote that orginally, my bad. The issue is that the data is getting passed as a list, not a string, and throwing an error. I'll look into it, thanks for the help.
1

One way is to use numpy.argsort combined with datetime library.

import numpy as np
from datetime import datetime

lst = ['March 1', 'March 9', 'April 14', 'March 12']

arr = np.array(lst)
res = arr[np.argsort([datetime.strptime(i+' 2018', '%B %d %Y') for i in lst])].tolist()

Result:

['March 1', 'March 9', 'March 12', 'April 14']

This is possible because, internally, dates are just numeric data. In this case, we attach an arbitrary year 2018 to create datetime objects.

Comments

1

You can also leverage the calendar module:

from calendar import month_name
months = list(month_name)

def parser (text):
    """Parses 'englishmonthname_whitespace_day-number' into string 'monthNR.dayNr'. 
    Will pad a zero to allow for string based sorting."""  
    try:
        month,day = text.split()
        monthAsIdx = months.index(month.strip())
        return '{:02d}.{:02d}'.format(monthAsIdx,int(day)) # return index in list.days
    except (ValueError, IndexError): # ValueError if not enough elements in string,
                                     # IndexError if not in list of month names
        return "99.99" # put last - all errors are put last w/o specific reordering

dates = ['TooFew', 'EnoughBut NotInList', 'March 1', 'March 9', 'April 14', 'March 12'] 

for n in dates:
    print(parser(n))


sortedDates = sorted(dates, key=lambda x: parser(x))

print(sortedDates)

Output:

# result of parser()
99.99
99.99
03.01
03.09
04.14
03.12

# sorted by key/lambda
['March 1', 'March 9', 'March 12', 'April 14', 'TooFew', 'EnoughBut NotInList'] 

Comments

1

You can use pandas module. Install it with pip.

You can do something like this:

import pandas as pd

dates = ['March 1', 'March 9', 'April 14', 'March 12']

df = pd.DataFrame(dates)
df = pd.to_datetime(df[0], format="%B %d")

df=df.sort_values() 

print (df)

This datetime format can be very useful like for example if you want the day or the month of an element of the list just do:

df.month
df.day

Comments

0

Possibilities:

  • Use a dictionary and use key/value
  • Use string matching (regex)
  • Many more ...

Or google and use any of these:

To provide a possible solution:

Input_list = [{'month':'March', 'day':30}, {'month':'March', 'day':10}]

newlist = sorted(Input_list, key=lambda k: k['month']) 

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.