libb.multikeysort

multikeysort(items, columns, inplace=False)[source]

Sort list of dictionaries by list of keys.

Equivalent to SQL ORDER BY - use no prefix for ascending, - prefix for descending.

Parameters:
  • items (list) – List of dictionaries to sort.

  • columns – List of column names to sort by (prefix with - for descending).

  • inplace (bool) – If True, sort in place; otherwise return new sorted list.

Returns:

Sorted list if inplace=False, otherwise None.

Basic Usage:

>>> ds = [
...     {'category': 'c1', 'total': 96.0},
...     {'category': 'c2', 'total': 96.0},
...     {'category': 'c3', 'total': 80.0},
...     {'category': 'c4', 'total': None},
...     {'category': 'c5', 'total': 80.0},
... ]
>>> asc = multikeysort(ds, ['total', 'category'])
>>> total = [_['total'] for _ in asc]
>>> assert all([cmp(total[i], total[i+1]) in (0,-1,)
...             for i in range(len(total)-1)])

Missing Columns are Ignored:

>>> us = multikeysort(ds, ['missing',])
>>> assert us[0]['total'] == 96.0
>>> assert us[1]['total'] == 96.0
>>> assert us[2]['total'] == 80.0
>>> assert us[3]['total'] == None
>>> assert us[4]['total'] == 80.0

None Columns are Handled:

>>> us = multikeysort(ds, None)
>>> assert us[0]['total'] == 96.0
>>> assert us[1]['total'] == 96.0
>>> assert us[2]['total'] == 80.0
>>> assert us[3]['total'] == None
>>> assert us[4]['total'] == 80.0

Descending Order with Inplace:

>>> multikeysort(ds, ['-total', 'category'], inplace=True) # desc
>>> total = [_['total'] for _ in ds]
>>> assert all([cmp(total[i], total[i+1]) in (0, 1,)
...             for i in range(len(total)-1)])