Как отсортировать по определенному атрибуту класса? - PullRequest
1 голос
/ 20 марта 2011

У меня есть модель с атрибутом, который отслеживает цену. Прямо сейчас у меня есть список этой определенной модели. Есть ли способ изменить список для сортировки по этому определенному атрибуту? Достаточно ли умен python, чтобы знать, что атрибут является значением, которое можно отсортировать? Я не отслеживаю экземпляры конкретной модели, используя базу данных (она не нужна для того, что я делаю, поэтому я не могу просто извлечь экземпляры из базы данных в отсортированном порядке) Спасибо!

Ответы [ 4 ]

4 голосов
/ 20 марта 2011

Вы можете использовать встроенную функцию sorted вместе с пользовательской функцией, которая возвращает цену объекта:

class Dummy(object) :
    pass

def getPrice(obj) :
    return obj.price

d0 = Dummy()
d0.price = 56.
d1 = Dummy()
d1.price=16.

d2 = Dummy()
d2.price=786.

d3 = Dummy()
d3.price=5.5

elements = [d0, d1, d2, d3]

print 'Pre-sorting:'
for elem in elements :
    print elem.price

sortedElements = sorted(elements, key=getPrice)

print 'Post-sorting:'
for elem in sortedElements :
    print elem.price

Это также будет работать через любой метод вашего класса, который возвращает цену, например,

class Dummy(object) :
    def __init__(self, price) :
        self._price = price
    def getPrice(self) :
        return self._price

...

sortedElements = sorted(elements, key = Dummy.getPrice)

Подробнее см. http://wiki.python.org/moin/HowTo/Sorting/.

2 голосов
/ 20 марта 2011

В качестве альтернативы вы можете использовать "operator.attrgetter ()":

list_of_objects.sort(key=operator.attrgetter('name_of_attribute_to_sort_by'))
0 голосов
/ 20 марта 2011

Лучшее место для поиска - http://wiki.python.org/moin/HowTo/Sorting

Лично функция класса __cmp__ намного удобнее при работе с классами, поскольку обычно вы всегда хотите сортировать их одинаково.

Вот несколько быстрых примеров:

class Foo :
    def __init__(self, x, y) :
        self.x = x
        self.y = y

    def __cmp__(self, x) :
        return cmp(self.x, x)

    def __repr__(self) :
        return "Foo(%d)" % self.x

# Simple list of objects
data = [
    Foo(1, 99),
    Foo(5, 94),
    Foo(6, 93),
    Foo(2, 97),
    Foo(4, 95),
    Foo(3, 96),
]

# sort using the __cmp__ class method - in numeric order
print sorted(data)

# sort using the key lambda, which reverse sorts... 
print sorted(data, key=lambda a : a.y)
0 голосов
/ 20 марта 2011

Для сортировки на месте вы можете использовать метод .sort для list, используя функцию, которая определяет ключ для сортировки.

>>> class Data(object):
...     def __init__(self,x,y):
...             self.x=x
...             self.y=y
... 
>>> l=[Data(i,i+1) for i in xrange(10,-1,-1)]
>>> print ", ".join("%s %s"%(x.x,x.y) for x in l)
10 11, 9 10, 8 9, 7 8, 6 7, 5 6, 4 5, 3 4, 2 3, 1 2, 0 1
>>> l.sort(key=lambda obj:obj.y)
>>> print ", ".join("%s %s"%(x.x,x.y) for x in l)
0 1, 1 2, 2 3, 3 4, 4 5, 5 6, 6 7, 7 8, 8 9, 9 10, 10 11

Чтобы получить еще один list, оставив исходный без изменений, используйте функцию sorted с необязательным параметром key, определенным аналогично.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...