对列表进行排序(自定义)

问题

users = [{'name': 'u2', 'age': 18, 'foo': 'a'},
         {'name': 'coldplay', 'age': 19, 'foo': 'b'},
         {'name': 'pink floyd', 'age': 25, 'foo': 'c'},
         {'name': 'the door', 'age': 15, 'foo': 'd'},
         {'name': 'eminem', 'age':40, 'foo': 'e'},
         {'name': '2pac', 'age':50, 'foo': 'f'},
         {'name': 'armstrong', 'age':60, 'foo': 'g'},
         {'name': 'ABBA', 'age':25, 'foo': 'h'}
        ]

按年龄排序

operator.itemgetter

from operator import itemgetter
print sorted(users, key=itemgetter('age'))

上面的结果中,我们发现有两个元素age相同,我们希望如果年龄相同,则按姓名排序呢?事实上,itemgetter可以传入两个参数。

print sorted(users, key=itemgetter('age','name'))

如果要给不支持比较操作的对象排序呢?

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

test = [Foo(12), Foo(23),Foo(5),Foo(3),Foo(8),Foo(66)]
test = sorted(test)
for t in test:
    print t.x

上面的代码中,我们创建了一个新的类,试图给一组Foo类的对象进行排序,但是失败了。思考一下,为啥int之间可以比较呢?原因很简单,因为int实现了cmp方法

print int.__cmp__

要想让Foo对象可以排序,首先我们要给Foo对象实现cmp方法

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

    def __cmp__(self, other):
        if self.x < other.x:
            return -1
        elif self.x > other.x:
            return 1
        else:
            return 0

assert Foo(13) > Foo(12)
assert Foo(12) == Foo(12)
assert Foo(11) < Foo(12)

test = [Foo(12), Foo(23),Foo(5),Foo(3),Foo(8),Foo(66)]
test = sorted(test)
for t in test:
    print t.x

现在Foo类的对象可比较了,也就可以排序了。

operator.attrgetter

from operator import attrgetter
test = [Foo(12), Foo(23),Foo(5),Foo(3),Foo(8),Foo(66)]
test2 = sorted(test, key=lambda t : t.x)
test1 = sorted(test, key=attrgetter('x'))

你可能感兴趣的:(对列表进行排序(自定义))