简体   繁体   中英

sort a list of string numerically in python

I know there are many questions regarding this type of sorting, I tried many time by referring to those questions and also by going through the re topic in python too

My question is:

class Example(models.Model):
    _inherit = 'sorting.example'

    def unable_to_sort(self):
        data_list = ['Abigail Peterson Jan 25','Paul Williams Feb 1','Anita Oliver Jan 24','Ernest Reed Jan 28']
        self.update({'list_of_birthday_week': ','.join(r for r in data_list)})

I need to be sorted according to the month & date like:

data_list = ['Anita Oliver Jan 24','Abigail Peterson Jan 25','Ernest Reed Jan 28','Paul Williams Feb 1']

is there any way to achieve this?

Use a regex to extract the date than use it as key of sorted function.

import re

pattern = r'(\b(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\D?(?:\d{1,2}\D?))'

sort_by_date = lambda x: datetime.strptime(re.search(pattern, x).group(0), '%b %d')
out = sorted(data_list, key=sort_by_date)

Output:

>>> out
['Anita Oliver Jan 24',
 'Abigail Peterson Jan 25',
 'Ernest Reed Jan 28',
 'Paul Williams Feb 1']

Input:

>>> data_list
['Abigail Peterson Jan 25',
 'Paul Williams Feb 1',
 'Ernest Reed Jan 28',
 'Anita Oliver Jan 24']

You need to extract the date part from the string, and then turn the date string into a comparable format. For the first task, regexen would be a decent choice here, and for the second part, datetime.strptime would be appropriate:

>>> import re
>>> from datetime import *
>>> 
>>> re.search('\w+ \d+$', 'Abigail Peterson Jan 25')
<re.Match object; span=(17, 23), match='Jan 25'>
>>> re.search('\w+ \d+$', 'Abigail Peterson Jan 25')[0]
'Jan 25'
>>> 
>>> datetime.strptime('Jan 25', '%b %d')
datetime.datetime(1900, 1, 25, 0, 0)
>>> datetime.strptime(re.search('\w+ \d+$', 'Abigail Peterson Jan 25')[0], '%b %d')
datetime.datetime(1900, 1, 25, 0, 0)

Then turn that into a callback for list.sort :

>>> data_list.sort(key=lambda i: datetime.strptime(re.search('\w+ \d+$', i)[0], '%b %d'))
['Anita Oliver Jan 24', 'Abigail Peterson Jan 25', 'Ernest Reed Jan 28', 'Paul Williams Feb 1']

You can also use split() to accomplish that.

from datetime import datetime
...
def unable_to_sort(self):
    data_list = ['Abigail Peterson Jan 25','Paul Williams Feb 1','Anita Oliver Jan 24','Ernest Reed Jan 28']
    
    def get_date(data):
        name, str_date = data.split(" ")[:-2], data.split(" ")[-2:]
        month, day = str_date
        return datetime.strptime(f"{month} {day}", "%b %d")
       
    sorted_data_list = sorted(data_list, key=get_date)     
    self.update({'list_of_birthday_week': ','.join(r for r in sorted_data_list)})

You can use sorted function with keys datetime.strptime() and date value.

from datetime import datetime
data_list = ['Anita Oliver Jan 24','Abigail Peterson Jan 25','Ernest Reed Jan 28','Paul Williams Feb 1']
k=[x.split() for x in data_list]
days_sorted = sorted(k, key=lambda x: (datetime.strptime(x[2],'%b'),x[3]))

[['Anita', 'Oliver', 'Jan', '24'],
 ['Abigail', 'Peterson', 'Jan', '25'],
 ['Ernest', 'Reed', 'Jan', '28'],
 ['Paul', 'Williams', 'Feb', '1']]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM