отсортировать список dicts по x, затем по y

#python #list #sorting

#python #Список #сортировка

Вопрос:

Я хочу отсортировать эту информацию (имя, точки и время):

 list = [
    {'name':'JOHN', 'points' : 30, 'time' : '0:02:2'},
    {'name':'KARL','points':50,'time': '0:03:00'}
]
  

итак, я хочу, чтобы список был отсортирован сначала по набранным очкам, затем по сыгранному времени (в моем примере Мэтт идет первым, потому что у него меньше времени. любая помощь?

Я пытаюсь с этим:

 import operator
list.sort(key=operator.itemgetter('points', 'time'))
  

но получил TypeError: list indices must be integers, not str .

Комментарии:

1. Какая версия python? Ваш пример работает на 2.7. Также, в качестве напоминания, «список» — это имя типа.

2. @koblas Возможно, я виноват. Этот пример работает и для меня сейчас, но я отредактировал вопрос, чтобы отформатировать исходный код, и непреднамеренно исправил синтаксическую ошибку в определении list . Игнорируя тот факт, что имя переменной list загромождает встроенный, как только синтаксическая ошибка неправильно завершающегося строкового литерала была исправлена, все заработало…

3. Проблема не в версии python, я использую python 2.6.6. И, извините, это моя ошибка, на самом деле list — это не мое имя переменной, я не знаю, почему я использую его здесь. Я думаю, что что-то не так с «временем воспроизведения», которое я преобразовал в строку…

Ответ №1:

Ваш пример работает для меня. Я бы посоветовал вам не использовать list в качестве имени переменной, поскольку это встроенный тип.

Вы также могли бы попробовать сделать что-то подобное:

 list.sort(key=lambda item: (item['points'], item['time']))
  

Ответ №2:

Редактировать:

пример списка:

 >>> a = [
...     {'name':'JOHN', 'points' : 30, 'time' : '0:02:20'},
...     {'name':'LEO', 'points' : 30, 'time': '0:04:20'},
...     {'name':'KARL','points':50,'time': '0:03:00'},
...     {'name':'MARK','points':50,'time': '0:02:00'},
... ]
  

по убыванию «точек»:

использование sort() для сортировки на месте:

 >>> a.sort(key=lambda x: (-x['points'],x['time']))
>>> pprint.pprint(a)
[{'name': 'MARK', 'points': 50, 'time': '0:02:00'},
 {'name': 'KARL', 'points': 50, 'time': '0:03:00'},
 {'name': 'JOHN', 'points': 30, 'time': '0:02:20'},
 {'name': 'LEO', 'points': 30, 'time': '0:04:20'}]
>>> 
  

использование sorted для возврата отсортированного списка:

 >>> pprint.pprint(sorted(a, key=lambda x: (-x['points'],x['time'])))
[{'name': 'MARK', 'points': 50, 'time': '0:02:00'},
 {'name': 'KARL', 'points': 50, 'time': '0:03:00'},
 {'name': 'JOHN', 'points': 30, 'time': '0:02:20'},
 {'name': 'LEO', 'points': 30, 'time': '0:04:20'}]
>>> 
  

по возрастанию «точек»:

 >>> a.sort(key=lambda x: (x['points'],x['time']))
>>> import pprint
>>> pprint.pprint(a)
[{'name': 'JOHN', 'points': 30, 'time': '0:02:20'},
 {'name': 'LEO', 'points': 30, 'time': '0:04:20'},
 {'name': 'MARK', 'points': 50, 'time': '0:02:00'},
 {'name': 'KARL', 'points': 50, 'time': '0:03:00'}]
>>> 
  

Комментарии:

1. В вашем примере МАРК должен быть первым, потому что у него больше очков, КАРЛ 2-й (те же очки, но больше времени) и так далее..

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

Ответ №3:

itemgetter выдаст эту ошибку вплоть до Python2.4

Если вы застряли на 2.4, вам нужно будет использовать лямбда

 my_list.sort(key=lambda x: (x['points'], x['time']))
  

Было бы предпочтительнее перейти на более новый Python, если это возможно