Sorting a list of strings by their components

The long list contains some sorting items.

Actually each element has 4 contents: name, in / out, scope and date and time, concatenated by '~. ("~" Can be changed.) I want to reorganize the list into sorted order.

a_list = ["Chris~Check-in~Zoom A~11/13/2013 05:20",
"Chris~Check-in~Zoom G~11/15/2013 14:09",
"Frank E~Check-in~Zoom K~11/11/2013 08:48",
"Frank E~Check-in~Zoom K~11/15/2013 21:32",
"Kala Lu S~Check-in~Zoom N~11/13/2013 07:20",
"Milly Emily~Check-in~Zoom G~11/13/2013 01:08",
"Milly Emily~Check-in~Zoom E~11/16/2013 14:39",
"Milly Amy~Check-in~Zoom G~11/10/2013 20:14",
"Milly Amy~Check-in~Zoom A~11/16/2013 08:55",
"Milly Amy~Check-in~Zoom O~11/14/2013 21:57",
"Milly Amy~Check-in~Zoom A~11/15/2013 10:45",
"Nago Iko~Check-in~Zoom K~11/16/2013 20:42",
"Nago Iko~Check-in~Zoom K~11/14/2013 10:46",
"Liz D~Check-in~Zoom N~11/15/2013 01:46",
"Liz D~Check-in~Zoom A~11/12/2013 09:54",
"Liz D~Check-in~Zoom G~11/16/2013 13:15",
"Chris~Check-out~Zoom A~11/13/2013 13:42",
"Chris~Check-out~Zoom G~11/11/2013 14:21",
"Chris~Check-out~Zoom G~11/16/2013 09:41",
"Frank E~Check-out~Zoom K~11/14/2013 03:02",
"House P~Check-out~Zoom K~11/10/2013 11:17",
"Kala Lu S~Check-out~Zoom G~11/11/2013 23:27",
"Kala Lu S~Check-out~Zoom N~11/14/2013 11:17"]

      

It can be imported into MS Excel and sorted, but I'm wondering if Python can do the job.

Is it possible to sort them in order in the list: 1. name, 2. date and time 3. area 4. entry / exit? How:

new_list = ["Chris~Check-out~Zoom G~11/08/2014 14:21",
"Chris~Check-in~Zoom A~11/10/2014 05:20",
"Chris~Check-out~Zoom A~11/10/2014 13:42",
"Chris~Check-in~Zoom G~11/12/2014 14:09",
"Chris~Check-out~Zoom G~11/13/2014 09:41",
"Frank E~Check-in~Zoom K~11/08/2014 08:48",
"Frank E~Check-out~Zoom K~11/11/2014 03:02",
"Frank E~Check-in~Zoom K~11/12/2014 21:32",
...
...]

      

Thank.

+3


source to share


2 answers


You can split the list and then sort it using a special function key

. But first you need to parse the date in order to sort them correctly.

import datetime

new_l = sorted((x.split('~') for x in l),
               key=lambda x: (x[0],
                              datetime.datetime.strptime(x[3], '%m/%d/%Y %H:%M'),
                              x[2],
                              x[1]))

      

The key function returns a tuple. Tuples are compared lexicographically; the first points are compared; if they are the same then other elements are compared, etc. [1]

Alternatively, you can sort in stages. This will allow you to specify columns to sort in ascending or descending order individually.

from operator import itemgetter

nl = [x.split('~') for x in l]

nl.sort(key=itemgetter(1))
nl.sort(key=itemgetter(2))
nl.sort(key=lambda x: datetime.datetime.strptime(x[3], '%m/%d/%Y %H:%M'),
        reverse=True) # Newest first
nl.sort(key=itemgetter(0))

      



Keep in mind that in both cases, the new list will be split like this:

new_list = [["Chris", "Check-out", "Zoom G", "11/08/2014 14:21"], ...]

      

If you want to change them back to the original form, you can join

:

new_list_joined = ['~'.join(x) for x in new_list]

      

+7


source


You can efficiently sort a list of strings in place by passing a key function to an inline method sort()

. All the key function that needs to be done is to return a tuple of values ​​extracted from a single element of the list, which is in the correct order and converted to the appropriate type for comparison if necessary:



import datetime

def custom_sort(string_list):
    def key_func(s, strptime=datetime.datetime.strptime):
        s = s.split('~')
        return s[0], strptime(s[3], '%m/%d/%Y %H:%M'), s[2], s[1]
    string_list.sort(key=key_func)

custom_sort(my_string_list)

      

0


source







All Articles