Python сортировка нескольких атрибутов - PullRequest
3 голосов
/ 29 ноября 2010

У меня есть словарь, подобный следующему. Пары значения ключа или имя пользователя: имя

d = {"user2":"Tom Cruise", "user1": "Tom Cruise"}

Моя проблема в том, что мне нужно отсортировать их по Имени, но если несколько пользователей содержат одно и то же имя, как указано выше, мне нужно отсортировать их по имени пользователя. Я посмотрел отсортированную функцию, но я не совсем понимаю параметр cmp и лямбда-выражения. Если бы кто-то мог объяснить это и помочь мне в этом, это было бы здорово! Спасибо:)

Ответы [ 3 ]

6 голосов
/ 29 ноября 2010

cmp устарел. lambda просто делает функцию.

sorted(d.iteritems(), key=operator.itemgetter(1, 0))
5 голосов
/ 29 ноября 2010

Я просто собираюсь уточнить ответ Игнасио Васкеса-Абрамса.cmp устарело.Не используйте это.Вместо этого используйте атрибут key.

lambda выполняет функцию.Это выражение, поэтому оно может идти в местах, недоступных обычному оператору def, но его тело ограничено одним выражением.

my_func = lambda x: x + 1

Это определяет функцию, которая принимает один аргумент, xи возвращает x + 1.lambda x, y=1: x + y определяет функцию, которая принимает аргумент x, необязательный аргумент y со значением по умолчанию 1 и возвращает x + y.Как видите, это действительно просто оператор def, за исключением того, что он является выражением и ограничен одним выражением для тела.

Цель атрибута key состоит в том, что sorted вызоветэто для каждого элемента последовательности, который нужно отсортировать и использовать значение, которое он возвращает для сравнения.

list_ = ['a', 'b', 'c']
sorted(list_, key=lambda x: 1)

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

  1. Вы не можете сортировать dict с.У вас есть список dicts с?Мы могли бы отсортировать это.
  2. Вы не показали ключ username.

Я предполагаю, что это что-то вроде

users = [{'name': 'Tom Cruise', 'username': user234234234, 'reputation': 1},
         {'name': 'Aaron Sterling', 'username': 'aaronasterling', 'reputation': 11725}]

Если вы хотите подтвердить, что я более удивительный, чем Том Круз, вы можете сделать следующее:

sorted(users, key=lambda x: x['reputation'])

Это просто передает функцию, которая возвращает значение 'reputation' для каждого словаря в списке.Но lambdas может быть медленнее.В большинстве случаев operator.itemgetter - это то, что вам нужно.

operator.itemgetter принимает серию ключей и возвращает функцию, которая принимает объект и возвращает кортеж значения его аргумента.

так f = operator.itemgetter('name', 'username') вернет, по сути, ту же функцию, что и lambda d: (d['name'], d['username']) Разница в том, что она должна, в принципе, работать намного быстрее, и вам не нужно смотреть на уродливые lambda выражения.

Так чтоСортируйте список dict s по имени, а затем по имени пользователя, просто сделайте

sorted(list_of_dicts, operator.itemgetter('name', 'username'))

, что именно то, что предложил Игнасио Васкес-Абрамс.

0 голосов
/ 29 ноября 2010

Вы должны знать, что dict не может быть отсортирован. Но в Python 2.7 и 3.1 есть коллекции этого класса. OrdderedDict.

Итак,

>>> from collections import OrderedDict
>>> d=OrderedDict({'D':'X','B':'Z','C':'X','A':'Y'})
>>> d
OrderedDict([('A', 'Y'), ('C', 'X'), ('B', 'Z'), ('D', 'X')])
>>> OrderedDict(sorted((d.items()), key=lambda t:(t[1],t[0])))
OrderedDict([('C', 'X'), ('D', 'X'), ('A', 'Y'), ('B', 'Z')])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...