0

I have a list that contains strings of dates; not only months ("Jan year x", "Feb year x"), but also Quarters ("Q1 of year x", "Q2 of year x") and seasons and years. The Seasons are "Winter" (October of year x to March of year x+1) and "Summer", defined as Apr of year x to Sep of year).

I want to sort the months from Jan to Dec of each year, then add the quarters after the three months that define, and then the seasons after the 6 months that define them, and finally the year after the 12 months that define them.

So, lets say the year is 2000, I would need to pass through these steps in order to get the end list:

  1. Sort the Months of the year:

    I would get:

    Jan 2000, Feb 2000, Mar 2000, Apr 2000, May 2000, Jun 2000, Jul 2000, Aug 2000,
    Sep 2000, Oct 2000, Nov 2000, Dec 2000
    
  2. Add the Quarters:

    Jan 2000, Feb 2000, Mar 2000, Q1 2000,Apr 2000, May 2000, Jun 2000,Q2 2000, Jul 2000,
    Aug 2000, Sep 2000, Q3 2000,Oct 2000, Nov 2000, Dec 2000, Q4 2000
    
  3. Add the Seasons:

    Jan 2000, Feb 2000, Mar 2000, Q1 2000, Win 1999, Apr 2000, May 2000, Jun 2000,Q2 2000,
    Jul 2000,Aug 2000, Sep 2000, Q3 2000, Sum 2000, Oct 2000, Nov 2000, Dec 2000, Q4 2000
    
  4. Last step, add the years:

    Jan 2000, Feb 2000, Mar 2000, Q1 2000, Win 1999, Apr 2000, May 2000, Jun 2000, Q2 2000,
    Jul 2000,Aug 2000, Sep 2000, Q3 2000, Sum 2000, Oct 2000, Nov 2000, Dec 2000, Q4 2000,
    Year 2000
    

Keep in mind these are all strings and not integers. The list that I begin with is this:

 temp2 = ['2015',
     '2016',
     '2017',
     '2018',
     '2019',
     '2020',
     'Apr-14',
     'Apr-15',
     'Apr-16',
     'Apr-17',
     'Aug-14',
     'Aug-15',
     'Aug-16',
     'Dec-14',
     'Dec-15',
     'Dec-16',
     'Feb-14',
     'Feb-15',
     'Feb-16',
     'Feb-17',
     'Jan-15',
     'Jan-16',
     'Jan-17',
     'Jul-14',
     'Jul-15',
     'Jul-16',
     'Jun-14',
     'Jun-15',
     'Jun-16',
     'Mar-14',
     'Mar-15',
     'Mar-16',
     'Mar-17',
     'May-14',
     'May-15',
     'May-16',
     'Nov-14',
     'Nov-15',
     'Nov-16',
     'Oct-14',
     'Oct-15',
     'Oct-16',
     'Q115',
     'Q116',
     'Q117',
     'Q214',
     'Q215',
     'Q216',
     'Q217',
     'Q314',
     'Q315',
     'Q316',
     'Q414',
     'Q415',
     'Q416',
     'Q417',
     'Sep-14',
     'Sep-15',
     'Sep-16',
     'Sum 14',
     'Sum 15',
     'Sum 16',
     'Sum 17',
     'Sum 18',
     'Win 14',
     'Win 15',
     'Win 16',
     'Win 17',
     'Win 18',
     'Win 19']

What I have tried is this:

temp3 = {}
    for i in range(len(temp2)):
        if temp2[i][0] == '2':
            temp3[temp2[i][2:]] = list()
    for i in range(len(temp2)):
        for key in temp3:
            if temp2[i][2:] == key:
                temp3[key].append(temp2[i])

then I am stumped as I don't know how to get the months of that year and not nothing.

Jongware
  • 22,200
  • 8
  • 54
  • 100
J.Doe
  • 166
  • 1
  • 9

2 Answers2

0

You need to first convert them all into the same format, then sort. So, convert into date format with something like the following:

from dateutil import parser

SEASONS = {"Win" : "Feb",
           "Spr" : "May",
           "Sum" : "Aug",
           "Aut" : "Nov"}

def convert_to_date(date_string):
    if date_string.startswith("Q"):
        quarter = int(date_string[1])
        month = str(quarter * 3)
        return parser.parse("{}-{}".format(month, date_string[2:]))
    elif date_string.startswith(tuple(SEASONS.keys())):
        month = SEASONS[date_string[:3]]
        return parser.parse("{}-{}".format(month, date_string.split(" ")[1]))
    else:
        return parser.parse(date_string)

Note that this puts the seasons at the last month as per comment.

You may need to pip install python-dateutil. Then it should be trivial to sort:

sorted_list = sorted(temp2, key=convert_to_date)
Aidenhjj
  • 1,249
  • 1
  • 14
  • 27
  • If you have formats that aren't exampled in your `temp2` variable, you need to include them in the conversion function. – Aidenhjj Jan 24 '18 at 10:11
-1
def fix_date(entry):
  if entry.startswith('Q'):
    return entry[:2] + ' 20{}'.format(entry[2:])
  elif '-' in entry:
    a, b = entry.split('-')
    return a + ' 20{}'.format(b)
  elif 'Win' in entry:
    a, b = entry.split(' ')
    b= int(b)+1
    b= str(b)
    return a + ' 20{}'.format(b)
  elif ' ' in entry:
    a, b = entry.split(' ')
    return a + ' 20{}'.format(b)
  else:
    return 'Year {}'.format(entry)

dates = [fix_date(x) for x in dates]

order = ['Jan', 'Feb', 'Mar', 'Q1', 'Win', 'Apr', 'May', 'Jun', 'Q2', 'Jul', 'Aug', 'Sep', 'Q3', 'Sum', 'Oct', 'Nov', 'Dec', 'Q4', 'Year']

dates_partial = [' '.join(pair) for pair in sorted([date.split() for date in dates], key=lambda x: (x[1], order.index(x[0])))]

def revert_date(entry):
  if entry.startswith('Q'):
    a, b = entry.split(' ')
    return a + b[2:]
  elif entry.startswith('Y'):
    a, b = entry.split(' ')
    return b
  elif 'Sum' in entry:
    a, b = entry.split(' ')
    return 'Sum' + b[2:]
  elif 'Win' in entry:
    a, b = entry.split(' ')
    b= int(b)-1
    b= str(b)
    return 'Win' + b[2:]
  else:
    a, b = entry.split(' ')
    return a + '-' +b[2:]

dates = [revert_date(x) for x in dates_partial]

Special thanks to @Ev Kounis his code:

https://repl.it/repls/PreviousTrimMite

J.Doe
  • 166
  • 1
  • 9