python operator 多属性排序_眼前一亮,又碰到一个实用的模块,以后python的各种运算就它了

在工作中,经常对数据进行各种运算,如要从一个序列中返回一个新的序列,亦或是要对两个数进行比较或者进行加和操作等。如果只是一个简单的运算,怎么都好办。但如果我们面对的是比较复杂的需求时,可能我们更多的是自己去实现一个类或方法 。

比如,要实现一个简单的加,减,乘,除的计算器。那我们的代码可能就是这样:

class Calc(object):    def add(self,a,b):        return a + b    def sub(self,a,b):        return a - b    def mul(self,a,b):        return a * b    def div(self,a,b):        return a / b

以上代码虽然只是一个demo演示,但是我们肯定会有类似逻辑运算,比较运算,赋值运算实现自定义的方法。

接下来就推荐一个不论什么运算,都可以搞定的包:operator.

operator模块

operator模块提供了一套与Python的内置运算符对应的高效率函数。我们常用到的算数运算符,比较运算符,位运算符,赋值运算符以及一些索引、切片等操作,在这个模块都支持 。

如上面的计算器需求,如果用operator的话,直接调用其内的方法即可 。打开operator模块的内部代码,可以看到它支持很多方法,具体如下:

__all__ = ['abs', 'add', 'and_', 'attrgetter', 'concat', 'contains', 'countOf',           'delitem', 'eq', 'floordiv', 'ge', 'getitem', 'gt', 'iadd', 'iand',           'iconcat', 'ifloordiv', 'ilshift', 'imatmul', 'imod', 'imul',           'index', 'indexOf', 'inv', 'invert', 'ior', 'ipow', 'irshift',           'is_', 'is_not', 'isub', 'itemgetter', 'itruediv', 'ixor', 'le',           'length_hint', 'lshift', 'lt', 'matmul', 'methodcaller', 'mod',           'mul', 'ne', 'neg', 'not_', 'or_', 'pos', 'pow', 'rshift',           'setitem', 'sub', 'truediv', 'truth', 'xor']

这些方法都是什么意思呢?我们可以通过一张图来做个比较。

d6a2b87bb1743642acd240c5e5253e6a.gif

常用方法介绍

iadd()介绍

以上方法中,大多数是比较好理解的,也有需要注意的地方,比如a+=b等同于iadd(a,b) 。对于数字来说,是两者相加,但是对于其它数据类型,就是两者相连接。但是不管是相加还是连接,对于不可变对象来说,通过iadd操作,其不改变原来的值,比如字符串,数字,元组。

import operatora = 'hello'print(operator.iadd(a,'python'))        #输出:hellopythonprint(a)                                #输出:hello,通过iadd并没有改变a的值a+='python'print(a)                                #输出:hellopython#两者的区别:a+=b相当于是将a+b后的值赋值a,而iadd(a,b)是将a+b进行运算后并不会再赋值给a

但是对于可变对象,如列表,字典 。两者的效果就是完全一样的。

a = [1,2,3]print(operator.iadd(a,[4])              #输出:[1,2,3,4]   等同于 a+=[4]print(a)                                #输出:[1,2,3,4]

序列操作

使用operator同样可以对序列进行操作,其典型的就是进行索引和切片。使用索引和切片一般都有三种方式,分别是通过索引取值,索引赋值,通过索引删除值。切片也是一样的。

主要使用的是如下三个方法:

#索引取值:operator.getitem(a,b)#索引赋值:operator.setitem(a,b,c)#索引删除值:delitem(a,b)#切片取值operator.getitem(a,slice(b,c))#切片赋值:operator.setitem(a,slice(b,c),d)#切片删除值:operator.delitem(a,slice(b,c))

具体实例:

lst = [1,2,3,4,5,6]dt = {'x':123,'y':456,'z':789}#索引获取值print("通过索引获取列表中第二个元素:",operator.getitem(lst,1))print("获取列表中第2~4个元素:",operator.getitem(lst,slice(1,4)))print("通过索引获取字典中y对应的值:",operator.getitem(dt,'y'))#索引赋值operator.setitem(lst, 2, 9)operator.setitem(dt,'z',234567)print("通过索引赋值后的列表元素:",lst)print("通过索引赋值后的字典元素:",dt)#索引删除值operator.delitem(lst,2)operator.delitem(dt,'z')print("通过索引删除后的列表元素:",lst)print("通过索引删除后的字典元素:",dt)#运行结果通过索引获取列表中第二个元素: 2获取列表中第2~4个元素: [2, 3, 4]通过索引获取字典中y对应的值: 456通过索引赋值后的列表元素: [1, 2, 9, 4, 5, 6]通过索引赋值后的字典元素: {'x': 123, 'y': 456, 'z': 234567}通过索引删除后的列表元素: [1, 2, 4, 5, 6]通过索引删除后的字典元素: {'x': 123, 'y': 456}

其它功能

除了以上方法外,operator还提供了一些用于查找的工具。这些工具适合用来编写快速字段提取器作为sorted(),map()等函数的参数 。

operator.attrgetter(attr)

传入(类)对象的某个属性(attr),返回一个可调用对象的元组 。一般attr为类的属性名 。

#语法:    operator.attrgetter(attr)       #attr为类的属性#实例class Student:    def __init__(self, name, grade, age,score):        self.name = name        self.grade = grade        self.age = age        self.score = score    def __repr__(self):        return repr((self.name, self.grade, self.age,self.score))        students = [        Student('张三', '6年级', 15,88),        Student('李四', '4年级', 12,88),        Student('王五', '7年级', 14,78),]print("按年级排序:",sorted(students, key=operator.attrgetter('grade')))print("先按成绩排序,再按年龄排序:",sorted(students, key=operator.attrgetter('score','age')))#结果:按年级排序: [('李四', '4年级', 12, 88), ('张三', '6年级', 15, 88), ('王五', '7年级', 14, 78)]先按成绩排序,再按年龄排序: [('王五', '7年级', 14, 78), ('李四', '4年级', 12, 88), ('张三', '6年级', 15, 88)]

在此实例中,首先创建了三条类对象的数据,使用sorted()方法进行数据排序,需要注意的是,sorted()排序需要指定key ,也就是按照这个key(键名)去排序,这里就是用到了operator.attrgetter()方法 ,直接指定类中的某个属性 进行排序。

operator.itemgetter(*items)

返回一个可调用对象,该对象从其操作数中获取给定项。 如果指定了多个条目,则返回一个查找值的元组。

#语法:    operator.itemgetter(item)       #返回operator.itemgetter(item),可以将该值用于sorted(),map()等。    operator.itemgetter(item)(seq)          #返回序列中某一个元素    operator.itemgetter(item1,item2,item3)(seq)     #返回多个元素组成的元组    operator.itemgetter(slice(n,m))                 #对序列进行切片    operator.itemgetter(key)(dict)              #获取字典中某个key的值   #实例:    s = 'ABCDEFG'    dt = {'a':123,'b':456}    student_list = [        {'name':'张三','grade':'6年级','age':15,'score':88},        {'name':'李四','grade':'4年级','age':12,'score':88},        {'name':'王五','grade':'7年级','age':14,'score':78},    ]    print("获取s的第2个元素:",operator.itemgetter(1)(s))    print("获取s的第2,4,6个元素:",operator.itemgetter(1,3,5)(s))    print("获取s的第3及往后的元素:",operator.itemgetter(slice(2,None))(s))    print("获取dt中key=a对应的值:",operator.itemgetter('a')(dt))    print(sorted(student_list, key=operator.itemgetter('name')))    #通过name进行排序。#结果:    获取s的第2个元素: operator.itemgetter(1)    获取s的第2,4,6个元素: ('B', 'D', 'F')    获取s的第3及往后的元素: CDEFG    获取dt中key=a对应的值: 123    [{'name': '张三', 'grade': '6年级', 'age': 15, 'score': 88}, {'name': '李四', 'grade': '4年级', 'age': 12, 'score': 88}, {'name': '王五', 'grade': '7年级', 'age': 14, 'score': 78}]

operator.methodcaller(name[, args...])

返回一个在操作数上调用 name 方法的可调用对象。 如果给出额外的参数和/或关键字参数,它们也将被传给该方法。

#语法    methodcaller('fun_name')        #fun_name为方法名,返回的是一个函数。#实例    class Square(object):        def __init__(self, length):            self.length = length        def get_area(self):            return pow(self.length,2)    if __name__ == '__main__':        s = Square(6)        print("正方形面积:",operator.methodcaller('get_area')(s))    #相当于s.get_area()

除此之外,此方法也可以直接调用已有的方法,比如

lst = ['x','y']f = operator.methodcaller('append','z') #调用列表中的append方法,向列表中添加一个z元素print("f的值:",f)f(lst)              #返回的是一个函数,print(lst)#输出:f的值: operator.methodcaller('append', 'z')['x', 'y', 'z']
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值