简体   繁体   中英

Python- Sorting a list of lists by multiple indices, where inner lists may include “None”

I am attempting to sort a list of lists by each index of the inner list. (All inner lists are the same length.) The goal is to sort the rows by the last column (the last index of the inner lists) first, then by the previous column/index and so on.

Input:

[
  ['2016', 'E', None, '68', '94'],
  ['2016', 'A', None, '91', '25'],
  ['2016', 'C', None, '74', '25'],
  ['2017', 'C', None, '55', '20'],
  ['2015', 'D', None, '20', '14'],
  ['2016', 'B', None, '66', '66'],
  ['2017', 'E', None, '29', '41'],
  ['2017', 'F', None, '61', '22'],
  ['2015', 'A', None, '17', '96']
]

Output:

[
  ['2015', 'A', None, '17', '96'],
  ['2015', 'D', None, '20', '14'],
  ['2016', 'A', None, '91', '25'],
  ['2016', 'B', None, '66', '66'],
  ['2016', 'C', None, '74', '25'],
  ['2016', 'E', None, '68', '94'],
  ['2017', 'C', None, '55', '20'],
  ['2017', 'E', None, '29', '41'],
  ['2017', 'F', None, '61', '22']
]

I have the following piece of code that I'm trying to use for this:

def sort_table(column_count, rows)
  for i in range(len(column_count) - 1, -1, -1):
    rows = sorted(rows, key=operator.itemgetter(i))
  return rows

However, it seems to be thrown by the fact that there are or can be None values in the list. I keep getting the error TypeError: '<' not supported between instances of 'NoneType' and 'str' . Is there a correct way to handle this?

Use sorted on your multidimensional list

l = [
  ['2016', 'E', None, '68', '94'],
  ['2016', 'A', None, '91', '25'],
  ['2016', 'C', None, '74', '25'],
  ['2017', 'C', None, '55', '20'],
  ['2015', 'D', None, '20', '14'],
  ['2016', 'B', None, '66', '66'],
  ['2017', 'E', None, '29', '41'],
  ['2017', 'F', None, '61', '22'],
  ['2015', 'A', None, '17', '96']
]
print(sorted(l))

prints

[['2015', 'A', None, '17', '96'], ['2015', 'D', None, '20', '14'], ['2016', 'A', None, '91', '25'], ['2016', 'B', None, '66', '66'], ['2016', 'C', None, '74', '25'], ['2016', 'E', None, '68', '94'], ['2017', 'C', None, '55', '20'], ['2017', 'E', None, '29', '41'], ['2017', 'F', None, '61', '22']]

Which is the same as your required output

Apart from the key , the sorted function also allows you to customize the comparator function, by passing a cmp argument. Just pass a function of two arguments that returns negative if the first argument is smaller, positive if it is larger, zero if they are equal. Depending on what you want, you could do something like

 import numpy as np

 def mycomparator(a, b):
     if a is None:
        return -1
     return np.sign(a - b)

 sorted(..., cmp=mycomparator, key=...)

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