Уведомления

Группа в Telegram: @pythonsu

#1 Сен. 5, 2012 15:24:31

369_sfera_963
Зарегистрирован: 2012-08-29
Сообщения: 7
Репутация: +  0  -
Профиль   Отправить e-mail  

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

Всем привет!

Допустим есть такой список:
buf = list( (“a”, 1), (“b”, 3), (“z”, 20), (“a”, 12) )

Нужно отсортировать его по второму столбцу (там где числа).
Как в sort (или sorted) использовать lambda функцию?

Отредактировано 369_sfera_963 (Сен. 5, 2012 15:26:57)

Офлайн

#2 Сен. 5, 2012 16:07:50

EBFE
Зарегистрирован: 2012-07-03
Сообщения: 99
Репутация: +  20  -
Профиль   Отправить e-mail  

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

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)]
>>>

Офлайн

#3 Сен. 5, 2012 16:36:06

369_sfera_963
Зарегистрирован: 2012-08-29
Сообщения: 7
Репутация: +  0  -
Профиль   Отправить e-mail  

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

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)]
>>>

Большое спасибо!

Офлайн

#4 Сен. 5, 2012 22:48:15

odnochlen
Зарегистрирован: 2012-06-28
Сообщения: 794
Репутация: +  14  -
Профиль   Отправить e-mail  

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

А можно список отсортировать по нескольким критериям за один проход?

Офлайн

#5 Сен. 6, 2012 01:31:32

EBFE
Зарегистрирован: 2012-07-03
Сообщения: 99
Репутация: +  20  -
Профиль   Отправить e-mail  

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

Намекаете на “классический” 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)

Офлайн

#6 Сен. 6, 2012 01:36:44

odnochlen
Зарегистрирован: 2012-06-28
Сообщения: 794
Репутация: +  14  -
Профиль   Отправить e-mail  

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

Намекаю на linq, где это можно сделать без лишних костылей и вполне читаемо.

В твоем примере, например, надо знать, как сравниваются кортежи + лишние затраты на их упаковку. В первом варианте вообще надо менять реализацию обьекта.

Офлайн

#7 Сен. 6, 2012 02:39:38

EBFE
Зарегистрирован: 2012-07-03
Сообщения: 99
Репутация: +  20  -
Профиль   Отправить e-mail  

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

В твоем примере, например, надо знать, как сравниваются кортежи
хуже
Еще желательно знать, как сравниваются списки
sorted(buf, key=lambda person: [person.name, person.city])
Ну и что не следует сравнивать set
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)

Офлайн

#8 Сен. 6, 2012 03:20:06

odnochlen
Зарегистрирован: 2012-06-28
Сообщения: 794
Репутация: +  14  -
Профиль   Отправить e-mail  

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

EBFE
хуже
Еще желательно знать, как сравниваются списки

sorted(buf, key=lambda person: )

Ну и что не следует сравнивать set

sorted(buf, key=lambda person: {person.name, person.city})
http://s019.radikal.ru/i644/1209/ec/24fd2f14bb9e.jpg

EBFE
Так лучше?
linq все равно круче

Офлайн

#9 Сен. 6, 2012 05:27:33

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8312
Репутация: +  568  -
Профиль   Отправить e-mail  

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

Господа, возникает закономерный вопрос, а чем, собственно, вариант с лямбдой хуже или лучше варианта с itemgetter? Есть какие-то предпочтения, обусловленные скоростью выполнения или расходом ресурсов?



Офлайн

#10 Сен. 6, 2012 05:39:27

PooH
От:
Зарегистрирован: 2006-12-05
Сообщения: 1948
Репутация: +  72  -
Профиль   Отправить e-mail  

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

EBFE
Намекаете на “классический” Comparator? В Py3 __cmp__ и cmp удалили http://python3porting.com/problems.html,
Чем он им помешал то?!



Вот здесь один из первых отарков съел лаборанта. Это был такой умный отарк, что понимал даже теорию относительности. Он разговаривал с лаборантом, а потом бросился на него и загрыз…

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version