Python-标准库之运算符替代函数Operator

operator 模块提供了一套与Python的内置运算符对应的高效率函数。例如,operator.add(x, y) 与表达式 x+y 相同。 许多函数名与特殊方法名相同,只是没有双下划线。为了向后兼容性,也保留了许多包含双下划线的函数。为了表述清楚,建议使用没有双下划线的函数。

函数包含的种类有:对象的比较运算、逻辑运算、数学运算以及序列运算。

操作 句法 Operator函数
a + b add(a, b)
串联 seq1 + seq2 concat(seq1, seq2)
成员测试 obj in seq contains(seq, obj)
a / b truediv(a, b)
整除 a // b floordiv(a, b)
按位与 a &b and_(a, b)
按位异或 a ^ b xor(a, b)
按位取反 〜 a invert(a)
按位或 a | b or_(a, b)
取幂 a ** b pow(a, b)
身份运算 a 是 b is_(a, b)
身份运算 a 是 不是 b is_not(a, b)
索引分配 obj [k] = v setitem(obj, k, v)
索引删除 del obj [k] delitem(obj, k)
索引取值 obj[k] getitem(obj, k)
左移 a b lshift(a, b)
取模 a % b mod(a, b)
a * b mul(a, b)
矩阵乘法 a @ b matmul(a, b)
取负 -a neg(a)
逻辑非 不是 a not_(a)
取正 +a pos(a)
右移 a >> b rshift(a, b)
切片赋值 seq [i:j] = 值 setitem(seq, slice(i, j), values)
删除切片 del seq [i:j] delitem(seq, slice(i, j))
切片 seq[i:j] getitem(seq, slice(i, j))
取模(同%) s % obj mod(s, obj)
a - b sub(a, b)
真相测试 obj truth(obj)
小于 a b lt(a, b)
小于等于 a b le(a, b)
等于 a == b eq(a, b)
不等于 a != b ne(a, b)
大于等于 a > = b ge(a, b)
大于 a > b gt(a, b)
import operator
from operator import *

#operator 模块提供了一套与Python的内置运算符对应的高效率函数

#逻辑操作
a = [1,2, 3]
b = a
print(operator.not_(a))     #False
print(operator.truth(a))    #True
print(operator.is_(a,b))    #True
print(operator.is_not(a,b))    #False

#比较操作符
a = 3
b = 10
print()
print(operator.lt(a,b),end=',',flush=True)    #小于
print(operator.le(a,b),end=',',flush=True)    #小于等于
print(operator.eq(a,b),end=',',flush=True)    #等于
print(operator.ne(a,b),end=',',flush=True)    #不等于
print(operator.gt(a,b),end=',',flush=True)    #大于
print(operator.ge(a,b),end='',flush=True)    #大于等于
#执行结果: True,True,False,True,False,False

#算术操作符
a = -1
b = 2
print()
print(operator.abs(a), end=',', flush=True)    #绝对值
print(operator.neg(a), end=',', flush=True)    #a的负值
print(operator.pos(a), end='', flush=True)    #a的正值
#执行结果:1,1,-1

a = -2
b = 5.0
print()
print(operator.add(a, b), end=',', flush=True)    #相加
print(operator.sub(a, b), end=',', flush=True)    #相减
print(operator.mul(a, b), end=',', flush=True)    #乘积
print(operator.mod(a, b), end=',', flush=True)    #取模
#执行结果:3.0    负数%负数=负数;   负数%正数=负数;   正数%负数=正数


a = [1,2,3]
b = ['a','b','c']
print()
print(operator.concat(a,b))     #返回a + b序列
# 执行结果:[1, 2, 3, 'a', 'b', 'c']

a = ['a', 1, 'b', 2]
b = 2
print(operator.contains(a, b))     #返回b in a
#执行结果:True

a = 'abaaacd'
b = 'a'
print(operator.countOf(a,b))     #返回b在a中出现的次数
#执行结果:4次

a = '1234456478'
b = '4'
print(operator.indexOf(a, b))      #返回b在a中第一次出现时的索引
#执行结果: 3

operator模块还定义了一些用于常规属性和条目查找的工具如:

  • attrgetter(attr)

  • itemgetter(item)

  • methodcaller(name/*args**kwargs)

这些工具适合用来编写快速字段提取器作为map(), sorted(), itertools.groupby()或其他需要相应函数参数的函数的参数

operator.attrgetter(): 可以获取对象的属性,然后进行排序操作,如请求了一个以上的属性,则返回一个属性元祖

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

    def __str__(self):
        return '%s(name = %r,age = %r, score = %r)' % (self.__class__.__name__,self.name,self.age,self.score)

    __repr__ = __str__
if __name__ == '__main__':
    std1 = Student('vv', 18, 99)
    std2 = Student('A', 5, 60)
    std3 = Student('B', 22, 100)
    std4 = Student('C', 30, 90 )

    students = [std1, std2, std3, std4]
    print(students)
    #按照分数排序 ,升序
    students.sort(key=lambda Student: Student.score, reverse=False)
    print(students)
    #返回结果:[Student(name = 'A',age = 5, score = 60), Student(name = 'C',age = 30, score = 90), Student(name = 'vv',age = 18, score = 99), Student(name = 'B',age = 22, score = 100)]

    #按照年龄排序,降序
    print(f"按照年龄排序:{sorted(students, key=attrgetter('age'),reverse=True)}")
    #返回结果:按照年龄排序:[Student(name = 'C',age = 30, score = 90), Student(name = 'B',age = 22, score = 100), Student(name = 'vv',age = 18, score = 99), Student(name = 'A',age = 5, score = 60)]

    #按照分数排序
    print(f"按照分数排序: {sorted(students,key=attrgetter('score'),reverse=False)}")
    #返回结果:按照分数排序: [Student(name = 'A',age = 5, score = 60), Student(name = 'C',age = 30, score = 90), Student(name = 'vv',age = 18, score = 99), Student(name = 'B',age = 22, score = 100)]

 operator.itemgetter(): 返回一个可调用对象,然后从它的操作数里面取值,默认调用__getiterm__()方法获取值

#1、用来排序
def func():
    data = [('a', 10), ('b', 15),('c', 19), ('d', 12), ('e', 17), ('f', 11)]
    data.sort(key=itemgetter(1), reverse=True)
    print(data)

func()
#返回结果:[('c', 19), ('e', 17), ('b', 15), ('d', 12), ('f', 11), ('a', 10)]

#用来获取多个值
s = itemgetter(1)('ABCDE')
print(s)
#返回结果:B

#传入多个item,返回一个元祖
s0 = itemgetter(1,3,5)('ABCDEFG')
print(s0)
#返回结果: ('B', 'D', 'F')

#与map一起用,从列表元祖中获取对应值或排序
s1 = [('apple',3), ('banana',2),('pear', 5),('orange',1)]
#print(list(map(__func=itemgetter(1), __iter1=s1)))  #返回map() takes no keyword arguments,指map无参数,写出来供参考
print(list(map(itemgetter(1), s1)))
#返回结果:[3, 2, 5, 1]

print(list(map(itemgetter(0),s1)))
#返回结果: ['apple', 'banana', 'pear', 'orange']

print(sorted(s1,key=itemgetter(1)))
#返回结果: [('orange', 1), ('banana', 2), ('apple', 3), ('pear', 5)]

 operator.methodcaller():通过字符串调用对象的方法


import math

class Point:
    def __init__(self,x,y):
        self.x = x
        self.y = y

    def __repr__(self):
        return 'Point({!r:},{!r:})'.format(self.x, self.y)

    def distance(self,x,y):
        return math.hypot(self.x -x, self.y -y)
#1、通过getattr()调用distance
p = Point(2, 3)
d = getattr(p,'distance')(0, 0)
print(d)
#返回结果:3.6055512754639896

#2、通过methodcaller()
p = Point(2, 3)
d = operator.methodcaller('distance', 0, 0)
print(d(p))
#返回结果:3.6055512754639896

#3、通过相同的参数多次调用某个方法,用methodcaller(),如需要排序一系列的点
points = [
    Point(1, 2),
    Point(3, 0),
    Point(10, -3),
    Point(-5, -7),
    Point(-1, 8),
    Point(3, 2)
]
points.sort(key=operator.methodcaller('distance', 0, 0))
print(points)
#返回结果: [Point(1,2), Point(3,0), Point(3,2), Point(-1,8), Point(-5,-7), Point(10,-3)]