python将对象放入列表根据某个属性排序_关于python:如何根据对象的属性对对象列表进行排序?...

我有一个python对象列表,我想按对象本身的属性排序。列表如下:

>>> ut

[, , , , ,

, ...]

每个对象都有一个计数:

>>> ut[1].count

1L

我需要按计数降序对列表进行排序。

我已经看到了几种方法,但我正在寻找Python中的最佳实践。

dupe:stackoverflow.com/questions/157424/…,stackoverflow.com/questions/222752/…,stackoverflow.com/questions/327191/…

为那些在Python中寻找更多排序信息的人排序。

除了operator.attrgetter("attribute_name")之外,您还可以使用functors作为键,如object_list.sort(key=my_sorting_functor("my_key"),从而故意放弃实现。

# To sort the list in place...

ut.sort(key=lambda x: x.count, reverse=True)

# To return a new list, use the sorted() built-in function...

newlist = sorted(ut, key=lambda x: x.count, reverse=True)

有关按键排序的更多信息»

没问题。顺便说一句,如果Muhuk是对的,并且它是Django对象的列表,那么您应该考虑他的解决方案。然而,对于排序对象的一般情况,我的解决方案可能是最佳实践。

在大列表中,使用operator.attrgetter("count")作为键可以获得更好的性能。这只是这个答案中lambda函数的一种优化(低级)形式。

谢谢你的回答。如果它是一个字典列表,并且"count"是它的键之一,则需要如下更改:ut.sort(key=lambda x:x["count"],reverse=true)

最快的方法是使用operator.attrgetter("count"),尤其是如果您的列表中有很多记录。但是,这可能在操作前版本的Python上运行,所以最好有一个回退机制。您可能需要执行以下操作:

try: import operator

except ImportError: keyfun= lambda x: x.count # use a lambda if no operator module

else: keyfun= operator.attrgetter("count") # use operator since it's faster than lambda

ut.sort(key=keyfun, reverse=True) # sort in-place

在这里,我将使用变量名"keyun"而不是"cmpun",以避免混淆。sort()方法也通过cmp=参数接受比较函数。

如果对象具有动态添加的属性(如果在__init__方法之后执行了self.__dict__ = {'some':'dict'},则这似乎不起作用。但我不知道为什么会不同。

@图卡:我从来没有替换过实例__dict__。注意,"动态添加属性的对象"和"设置对象的__dict__属性"几乎是正交概念。我是说,因为您的评论似乎意味着设置__dict__属性是动态添加属性的要求。

@Tzot:我现在看到的是:github.com/randomatic technologies/goatfish/blob/master/…,这里使用该迭代器:github.com/tallertechnologies/dishey/blob/master/app.py l28会引发属性错误。也许是因为Python3,但是…

@图卡:我会用self.__dict__.update(kwargs)代替self.__dict__= kwargs。在任何情况下,也许这是一个python 3问题,因为2.7.3看起来运行正常。稍后我将使用python 3进行研究。

然后就是这样,这可能意味着类模型的元类在这里是错误的。

@Tzot,它与Django无关,goatfish元属性只是一个没有魔法的原始对象…我已经在一个Python2.7项目中测试过了它,并且看起来像预期的那样工作。我需要进一步了解这个问题…

@Tzot:如果我了解operator.attrgetter的用法,我可以提供一个具有任何属性名的函数,并返回一个已排序的集合。

对于那些想了解更多信息的人:wiki.python.org/moin/howto/sorting operator_module_函数

读者应该注意到key=方法:

ut.sort(key=lambda x: x.count, reverse=True)

比向对象添加丰富的比较运算符快很多倍。我很惊讶地读到了这篇文章(第485页的"简而言之,Python")。您可以通过在这个小程序上运行测试来确认这一点:

#!/usr/bin/env python

import random

class C:

def __init__(self,count):

self.count = count

def __cmp__(self,other):

return cmp(self.count,other.count)

longList = [C(random.random()) for i in xrange(1000000)] #about 6.1 secs

longList2 = longList[:]

longList.sort() #about 52 - 6.1 = 46 secs

longList2.sort(key = lambda c: c.count) #about 9 - 6.1 = 3 secs

我的,非常小的,测试显示第一种速度慢了10倍以上,但书中说一般来说只有5倍左右。他们说这是因为python(timsort)中使用了高度优化的排序算法。

不过,非常奇怪的是.sort(lambda)比普通的old.sort()更快。我希望他们能解决这个问题。

from operator import attrgetter

ut.sort(key = attrgetter('count'), reverse = True)

面向对象方法

如果适用,最好将对象排序逻辑设置为类的属性,而不是将其合并到需要排序的每个实例中。

这确保了一致性,并消除了对样板代码的需求。

至少,您应该指定__eq__和__lt__操作,这样才能工作。那就用sorted(list_of_objects)。

class Card(object):

def __init__(self, rank, suit):

self.rank = rank

self.suit = suit

def __eq__(self, other):

return self.rank == other.rank and self.suit == other.suit

def __lt__(self, other):

return self.rank < other.rank

hand = [Card(10, 'H'), Card(2, 'h'), Card(12, 'h'), Card(13, 'h'), Card(14, 'h')]

hand_order = [c.rank for c in hand]  # [10, 2, 12, 13, 14]

hand_sorted = sorted(hand)

hand_sorted_order = [c.rank for c in hand_sorted]  # [2, 10, 12, 13, 14]

考虑到最初的IMO用例,这是一个更聪明的解决方案——我认为这应该是投票率最高的答案。

它看起来很像django-orm模型实例的列表。

为什么不在查询时这样排序:

ut = Tag.objects.order_by('-count')

是的,但是使用django标记,所以我使用一个内置的工具来抓取特定查询集使用的标记集,如so:tag.objects.usage for_queryset(query set,counts=true)

向对象类添加丰富的比较运算符,然后使用列表的sort()方法。请参阅python中的丰富比较。

更新:虽然这个方法可行,但我认为TripTych的解决方案更适合您的情况,因为它更简单。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,根据您的要求,我可以为您提供以下Python代码: ```python class Student: def __init__(self, name, math_score, english_score, science_score): self.name = name self.math_score = math_score self.english_score = english_score self.science_score = science_score self.total_score = math_score + english_score + science_score def sort_students(students): return sorted(students, key=lambda student: student.total_score, reverse=True) if __name__ == '__main__': students = [] while True: name = input('请输入学生姓名(输入exit结束输入):') if name == 'exit': break math_score = int(input('请输入学生数学成绩:')) english_score = int(input('请输入学生英语成绩:')) science_score = int(input('请输入学生科学成绩:')) student = Student(name, math_score, english_score, science_score) students.append(student) students = sort_students(students) print('按照总分排序后的学生名单如下:') for i, student in enumerate(students): print('{}、{},总分:{}'.format(i+1, student.name, student.total_score)) ``` 这段代码会先定义一个名为 `Student` 的类,包含四个属性:名字、数学成绩、英语成绩和科学成绩。在类的构造函数中,我们会通过传入的参数来初始化这些属性,并计算学生的总分。 接着,我们定义了一个名为 `sort_students` 的函数,它会接受一个学生列表作为参数,并根据学生的总分进行排序。具体实现是通过调用Python内置函数 `sorted`,并传入一个 `key` 函数作为参数,这个函数会告诉 `sorted` 如何比较学生的大小。具体而言,我们定义了一个 `lambda` 表达式,它会接受一个学生对象作为输入,并返回这个学生对象的总分。 最后,在 `if __name__ == '__main__':` 下,我们编写了一个简单的交互式程序。程序会循环读入输入,每次输入一个学生的信息,直到用户输入 `exit` 结束输入。我们会将输入的学生对象放入一个列表中,并调用 `sort_students` 函数来对学生列表进行排序。最后,我们将排序后的学生信息输出到屏幕上。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值