py 自定义对象的排序比较,等值判断及hash求值

is 与 == 两种相等判断

  • id(obj)
    built-in 方法, 返回对象的内存地址, 一旦对象被创立, 整个生命周期内不变.
  • is 是关键字, 等价于 id(a) == id(b) .
  • object#__eq__(self, x)
    对象间的==运算符, 就会调用该方法, 看不到源码, 资料显示默认是 id 比较, 也即 引用地址比较, 这样就跟 java 习惯一样了.

排序 与 比较

直接比较会报错.

>>> 2 < '2'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unorderable types: int() < str()

运算符重载

__lt__,__eq__这些方法的返回都是bool类型.
例子

class Student:
    def __init__(self,score:int):
        self.score=score

    # 写了'<'的判别标准, '>' 的自动就有了, 不需要再写`__gt__()`
    def __lt__(self, other):
        return self.score < other.score
    # 写了 == 的判别标准
    def __eq__(self, other):
        return self.score == other.score

    def __str__(self):
        return "score {}".format(self.score)


a= Student(1)
b= Student(2)
c= Student(1)

my_list=[c,b,a]
print("before sort. "+ ','.join(map(str,my_list)))
my_list.sort()
print("after sort. "+ ','.join(map(str,my_list)))
print(a>b)
"""
before sort. score 1,score 2,score 1
after sort. score 1,score 1,score 2
False
"""

sorted

sorted(iterable, cmp=None, key=None, reverse=False) 它不会改变实参, 会返回新的有序集合.
默认升序排序.

  • iterable
    可以是list, dict等.
  • cmp
    有两个形参的函数. 这种函数返回true 或 false.
  • key
    有一个形参的函数. 这种函数会返回一个数值, 用于比较.

例子

class Student:
    def __init__(self, num, score):
        self.num=num
        self.score=score
    @staticmethod
    def showList(list):
        for x in list:
            print('num:'+str(x.num) + '\tscore:'+str(x.score))
        print('---')
    
arr=[Student(1001,100),Student(1002,90)]
#学号升序
Student.showList(sorted(arr,key=lambda x :x.num))
#成绩升序
Student.showList(sorted(arr,key=lambda x :x.score))
#成绩升序
Student.showList(sorted(arr,cmp=lambda x,y :x.score-y.score))

还可以按照dict的value进行排序.

import operator
dict={}
dict[1]=2
dict[2]=4
dict[3]=0

dict_sorted=sorted(dict.iteritems(),key=operator.itemgetter(1))
# 上下两种写法一样
dict_sorted=sorted(dict.iteritems(),key=lambda x:x[1])
print dict
print dict_sorted[0].__class__
print dict_sorted.__class__
# dict_sorted 类型是list<tuple>
"""
{1: 2, 2: 4, 3: 0}
<type 'tuple'>
<type 'list'>
"""

list.sort()

list.sort(cmp=None, key=None, reverse=False) , 原地算法(in-place), (c 中习惯称变异算法), 没有返回值, 会改变自身元素顺序.

tuple作为列表元素排序

有时我们不想定义一个类, 方便起见直接用 tuple表示一个对象的若干属性, Q: 此时应该怎么对 List[Tuple] 排序呢?
A: 在list的sort方法中可以直接用lambda表达式指定key

Q: 如果不指定, 默认的规则是啥呢?
A: 详见参考[4].

hash方法

覆写__hash__()方法.
一般来讲, 覆写__hash__()的时候, 都要同时覆写__eq__(self,other)方法.

参考

  1. python-sorting-objects-of-user-defined-class
  2. s.o.f making-a-python-user-defined-class-sortable-hashable
  3. s.o.f how-python-priorityqueue-works-with-irregular-tuple-object
  4. my blog, 元组tuple
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值