【发布时间】:2011-03-20 09:04:00
【问题描述】:
我有一个带有跟踪价格属性的模型。现在,我有一个特定型号的列表。无论如何要重新排列列表以按该特定属性排序? python是否足够聪明,可以知道属性是一个可以排序的值?我没有使用数据库跟踪特定模型的实例(我正在做的事情不需要它,所以我不能只按排序顺序从数据库中检索实例) 谢谢!
【问题讨论】:
我有一个带有跟踪价格属性的模型。现在,我有一个特定型号的列表。无论如何要重新排列列表以按该特定属性排序? python是否足够聪明,可以知道属性是一个可以排序的值?我没有使用数据库跟踪特定模型的实例(我正在做的事情不需要它,所以我不能只按排序顺序从数据库中检索实例) 谢谢!
【问题讨论】:
您可以使用内置的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/ 了解更多信息。
【讨论】:
您也可以使用operator.attrgetter():
list_of_objects.sort(key=operator.attrgetter('name_of_attribute_to_sort_by'))
【讨论】:
要进行就地排序,您可以使用list 的.sort 方法,使用定义排序键的函数。
>>> 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 参数。
【讨论】:
最好看的地方是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)
【讨论】: