【问题标题】:Python sorting - A list of objectsPython 排序 - 对象列表
【发布时间】:2011-01-21 06:21:56
【问题描述】:

如果可能的话,我想使用 somelist.sort() 方法来做到这一点。

我有一个包含对象的列表,所有对象都有一个成员变量 resultType,它是一个整数。我想使用这个数字对列表进行排序。

我该怎么做?

谢谢!

【问题讨论】:

    标签: python list sorting


    【解决方案1】:
    somelist.sort(key = lambda x: x.resultType)
    

    这是您经常看到的另一种执行相同操作的方法:

    import operator
    s.sort(key = operator.attrgetter('resultType'))
    

    如果您还没有看过sorted,您可能还想看看它。它不会修改原始列表 - 它返回一个新的排序列表。

    【讨论】:

    • 您回答了我的两个问题(attrgetter..)并指出了一些有用的东西。谢谢!
    • 您帮助我了解了 sorted 与 sort 的不同之处!谢谢
    【解决方案2】:

    当然,它不一定是 lambda。任何传入的函数,例如下面的函数,都可以工作

    def numeric_compare(x, y):
       if x > y:
          return 1
       elif x == y:
          return 0
       else:  #x < y
          return -1
    
    a = [5, 2, 3, 1, 4]
    a.sort(numeric_compare)
    

    来源:Python Sorting

    所以,在你的情况下......

    def object_compare(x, y):
       if x.resultType > y.resultType:
          return 1
       elif x.resultType == y.resultType:
          return 0
       else:  #x.resultType < y.resultType
          return -1
    
    a.sort(object_compare)
    

    前面提到的 lambda 绝对是最紧凑的方法,但也有使用 operator.itemgetter

    import operator
    #L = [('c', 2), ('d', 1), ('a', 4), ('b', 3)]
    map(operator.itemgetter(0), L)
    #['c', 'd', 'a', 'b']
    map(operator.itemgetter(1), L)
    #[2, 1, 4, 3]
    sorted(L, key=operator.itemgetter(1))
    #[('d', 1), ('c', 2), ('b', 3), ('a', 4)]
    

    所以你会使用 itemgetter('resultType')。 (假设 getitem 已定义。)

    sorted(L, key=operator.itemgetter('resultType'))
    

    【讨论】:

    • cmp 已被弃用 - 在 Python3 中甚至不存在。您应该改用键功能。
    • 谢谢你。我总是喜欢看到非 lambda 的做事方式,即使我最终会使用 lambda 版本(感觉更性感)
    • 谢谢 Rizwan。比较方法很有帮助
    【解决方案3】:
    somelist.sort(cmp = lambda x, y: cmp(x.resultType, y.resultType))
    

    优于:

    somelist.sort(key = lambda x: x.resultType)
    

    在第一种情况下,我们传入一个比较函数,用于成对比较列表中的元素。在第二种情况下,我们分配一个新的键函数结果对列表,以及原始值。然后我们对该列表进行排序,然后从对中删除键值。如果您的比较函数很昂贵,这非常有用,但如果比较真的很便宜,则只会浪费内存。

    即密钥版本的扩展看起来是这样的:

    l = [y for x,y in sorted(zip([key(i) for i in l], l))]
    

    对于一个简单的 key 函数,显然开销太大,所以我建议使用更轻的基于函数的排序。

    注意cmp函数参数在小于、等于和大于的情况下需要返回-1,0,1。你可以自己写,但你也可以使用内置的 cmp 函数,它更清晰。

    【讨论】:

    • 叹气,谢谢@gnibbler,我不知道cmp 参数在Python 3 中已被弃用,很高兴知道。但是如果你在python 2.x,我认为它比key版本更清晰、更高效。在 Python 3 中,我会关注 Mark Byers。
    【解决方案4】:

    对于 Python 3.x,用户必须提供一个键函数。 Source

    def cmp_to_key(mycmp):
    'Convert a cmp= function into a key= function'
    class K(object):
        def __init__(self, obj, *args):
            self.obj = obj
        def __lt__(self, other):
            return mycmp(self.obj, other.obj) < 0
        def __gt__(self, other):
            return mycmp(self.obj, other.obj) > 0
        def __eq__(self, other):
            return mycmp(self.obj, other.obj) == 0
        def __le__(self, other):
            return mycmp(self.obj, other.obj) <= 0
        def __ge__(self, other):
            return mycmp(self.obj, other.obj) >= 0
        def __ne__(self, other):
            return mycmp(self.obj, other.obj) != 0
    return K
    >>> sorted([5, 2, 4, 1, 3], key=cmp_to_key(reverse_numeric))
    [5, 4, 3, 2, 1]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-03
      • 2011-02-24
      • 1970-01-01
      • 1970-01-01
      • 2019-07-18
      • 1970-01-01
      相关资源
      最近更新 更多