Сортировать строку-матрицу [[a, b, c], ...] по a, -c, b, поддерживая порядок? - PullRequest
1 голос
/ 13 марта 2012

У меня есть список списков из трех строк в Python, например,

m = [['pig', 'quartz', '1'], ['pork', 'nails', '1'], ...]

и я хочу отсортировать его по индексу 0, затем по индексу 2 в обратном порядке, затем по индексу 1. На каждом этапе сортировки я хотел бы поддерживать порядок, налагаемый другими столбцами. Например,

pork       barn         4
pork       barn2        4
pork       nails        1
pig        quartz       1
quinoa     pail         1
quinoa     quatern      1
quail      quatern      1
radish     barn         1
radish     barn2        1
radish     inbox        3
radish     snow         1

станет:

pig        quartz       1
pork       barn         4
pork       barn2        4
pork       nails        1
quail      quatern      1
quinoa     pail         1
quinoa     quatern      1
radish     inbox        3    <-
radish     barn         1
radish     barn2        1
radish     snow         1

то есть сортировка по первому столбцу, затем в каждой группе 1-го столбца (свинья, свинина, перепел, ...), сортировка по обратному третьему столбцу, затем в каждой группе 1-го столбца-3-го столбца ((свинья, 1), (свинина, 4), (свинина, 1), ...), сортировка по второму столбцу.

Как я могу сделать это красиво? Концептуально, если бы operator.itemgetter() мог кодировать порядок сортировки вместе с индексом, я бы хотел что-то вроде m.sort(key=operator.itemgetter(0, -2, 1)).

Ответы [ 3 ]

4 голосов
/ 13 марта 2012
def key(item):
    return item[0], -int(item[2]), item[1]
m.sort(key = key)

PS.Ключевое слово cmp было удалено из Python3 .Для будущей совместимости вы можете придерживаться key.

2 голосов
/ 13 марта 2012

Я бы попробовал что-то вроде этого:

def sort_key(a, b, c):
   return (a, -int(c) , b)           

m.sort(key = lambda row: sort_key(*row))
1 голос
/ 13 марта 2012

Используйте пользовательскую функцию сравнения:

def compare_triples(a, b):
    ret=cmp(a[0], b[0])
    if ret: return ret
    ret=cmp(b[2], a[2])
    if ret: return ret
    return cmp(a[1], b[1])

for i in m: print i
print "-" * 79
m2=sorted(m, cmp=compare_triples)
for i in m2: print i

Функция сравнения не является оптимальной и может быть переписана как:

def compare_triples(a, b):
    return cmp((a[0], b[2], a[1]), (b[0], a[2], b[1]))

Как уже отмечали другие, это тоже будет работать:

def sort_key(a):
    return a[0], -int(a[2]), a[1]

for i in sorted(m, key=sort_key): print i
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...