Форум сайта python.su
0
Всем привет!
Допустим есть такой список:
buf = list( (“a”, 1), (“b”, 3), (“z”, 20), (“a”, 12) )
Нужно отсортировать его по второму столбцу (там где числа).
Как в sort (или sorted) использовать lambda функцию?
Отредактировано 369_sfera_963 (Сен. 5, 2012 15:26:57)
Офлайн
20
http://wiki.python.org/moin/HowTo/Sorting/
>>> sorted(buf,cmp = lambda x,y: cmp(x[1],y[1])) [('a', 1), ('b', 3), ('a', 12), ('z', 20)] >>> sorted(buf,key=lambda x: x[1]) [('a', 1), ('b', 3), ('a', 12), ('z', 20)] >>> from operator import itemgetter >>> sorted(buf,key=itemgetter(1)) [('a', 1), ('b', 3), ('a', 12), ('z', 20)] >>>
Офлайн
0
EBFE
http://wiki.python.org/moin/HowTo/Sorting/>>> sorted(buf,cmp = lambda x,y: cmp(x[1],y[1])) [('a', 1), ('b', 3), ('a', 12), ('z', 20)] >>> sorted(buf,key=lambda x: x[1]) [('a', 1), ('b', 3), ('a', 12), ('z', 20)] >>> from operator import itemgetter >>> sorted(buf,key=itemgetter(1)) [('a', 1), ('b', 3), ('a', 12), ('z', 20)] >>>
Офлайн
14
А можно список отсортировать по нескольким критериям за один проход?
Офлайн
20
Намекаете на “классический” Comparator? В Py3 __cmp__ и cmp удалили http://python3porting.com/problems.html,
но в принципе, в классах достаточно реализации “lower than” (__lt__).
Ну или передавать все критерии в sort:
>>> class Person(object): ... def __init__(self, name, age, city): ... self.name = name ... self.age = age ... self.city = city ... def __lt__(self, other): # сортирем по возрасту и имени ... return (self.age, self.name) < (other.age, other.name) ... def __repr__(self): ... return "({0},{1},{2})".format(self.name, self.age, self.city) ... >>> buf = [Person("Alice",21,"Redmond"),Person("Bob",20,"Boston"), ... Person("Nadine",21,"Denver")] >>> sorted(buf) [(Bob,20,Boston), (Alice,21,Redmond), (Nadine,21,Denver)]
>>> def keyfunc(person): ... return person.age, person.city ... >>> sorted(buf, key=keyfunc) [(Bob,20,Boston), (Nadine,21,Denver), (Alice,21,Redmond)] >>> sorted(buf, key=lambda person: (person.age, person.city)) [(Bob,20,Boston), (Nadine,21,Denver), (Alice,21,Redmond)] >>> sorted(buf, key=lambda person: (person.name, person.city)) [(Alice,21,Redmond), (Bob,20,Boston), (Nadine,21,Denver)] >>> sorted(buf, key=lambda person: (person.name[-1], person.city)) #последняя буква имени, город [(Bob,20,Boston), (Nadine,21,Denver), (Alice,21,Redmond)]
Отредактировано EBFE (Сен. 6, 2012 01:35:39)
Офлайн
14
Намекаю на linq, где это можно сделать без лишних костылей и вполне читаемо.
В твоем примере, например, надо знать, как сравниваются кортежи + лишние затраты на их упаковку. В первом варианте вообще надо менять реализацию обьекта.
Офлайн
20
В твоем примере, например, надо знать, как сравниваются кортежихуже

sorted(buf, key=lambda person: [person.name, person.city])
sorted(buf, key=lambda person: {person.name, person.city})
>>> from operator import attrgetter, itemgetter >>> sorted(buf, key=attrgetter('age', 'city')) [(Bob,20,Boston), (Nadine,21,Denver), (Alice,21,Redmond)] >>> sorted([(3,1),(2,1),(4,0)], key=itemgetter(1,0)) [(4, 0), (2, 1), (3, 1)] >>> sorted(buf, key=attrgetter('age', 'name')) [(Bob,20,Boston), (Alice,21,Redmond), (Nadine,21,Denver)]
Отредактировано EBFE (Сен. 6, 2012 02:54:27)
Офлайн
14
EBFEhttp://s019.radikal.ru/i644/1209/ec/24fd2f14bb9e.jpg
хуже
Еще желательно знать, как сравниваются списки
sorted(buf, key=lambda person: )
Ну и что не следует сравнивать set
sorted(buf, key=lambda person: {person.name, person.city})
EBFElinq все равно круче
Так лучше?

Офлайн
568
Господа, возникает закономерный вопрос, а чем, собственно, вариант с лямбдой хуже или лучше варианта с itemgetter? Есть какие-то предпочтения, обусловленные скоростью выполнения или расходом ресурсов?
Офлайн
72
EBFEЧем он им помешал то?!
Намекаете на “классический” Comparator? В Py3 __cmp__ и cmp удалили http://python3porting.com/problems.html,
Офлайн