【Python】operator模块

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

不仅对应内置运算符,还可以获取方法。可优化涉及回调函数的运算性能,比lambda、Python函数的开销小、速度快。

python 复制代码
import operator

[x for x in dir(operator) if not x.startswith('_')]
# 结果:
['abs', 'add', 'and_', 'attrgetter', 'call', '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']

from operator import *

1、数学运算

注意:数字不可变。因此,原地运算符,会被计算,但不会被赋值,不改变原变量的数字。

|----------------|-----------|----------------------------------------------------------------------------------------------------------|------------------------------------|
| 函数 | 对应运算符 | 描述 | 举例 |
| add(a,b) | a + b | 相加 | add(2,3) 结果:5 |
| iadd(a,b) | a += b | 相加,原地运算符 | a = 5 iadd(a,3) 结果:8 a 结果:5 |
| sub(a,b) | a - b | 相减 | sub(2,3) 结果:-1 |
| isub(a,b) | a -= b | 相减,原地运算符 | |
| mul(a,b) | a * b | 相乘 | mul(2,3) 结果:6 |
| imul(a,b) | a *= b | 相乘,原地运算符 | |
| truediv(a,b) | a / b | 相除 | truediv(2,3) 结果:0.6666666666666666 |
| itruediv(a,b) | a /= b | 相除,原地运算符 | |
| floordiv(a,b) | a // b | 相除取整数 | floordiv(2,3) 结果:0 |
| ifloordiv(a,b) | a //= b | 相除取整数,原地运算符 | |
| mod(a,b) | a % b | 相除取余数 | mod(2,3) 结果:2 |
| imod(a,b) | a %= b | 相除取余数,原地运算符 | |
| pow(a,b) | a ** b | 幂, | pow(2,3) 结果:8 |
| ipow(a,b) | a **= b | 幂,原地运算符 | |
| matmul(a,b) | a @ b | 矩阵乘法 | |
| imatmul(a,b) | a @= b | 矩阵乘法,原地运算符 | |
| neg(a) | - a | 算术取反 | neg(1) 结果:-1 |
| pos(a) | + a | 取正 | pos(-1) 结果:-1 |
| abs(a) | | 绝对值 | abs(-1) 结果:1 |

|-------------------|-----------|---------------|--------------------------------|
| 函数 | 对应运算符 | 描述 | 举例 |
| inv(a), invert(a) | | 按位取反,等价于 ~ a | ① inv(2) 结果:-3 invert(2) 结果:-3 |
| lshift(a,b) | a << b | 左移 | ② lshift(2,3) 结果:16 |
| ilshift(a,b) | a <<= b | 左移,原地运算符 | |
| rshift(a,b) | a >> b | 右移 | rshift(2,3) 结果:0 |
| irshift(a,b) | a >>= b | 右移,原地运算符 | |
| and_(a,b) | a & b | 按位与 | ③ and_(2,3) 结果:2 |
| iand(a,b) | a &= b | 按位与,原地运算符 | |
| or_(a,b) | a | b | 按位或 | or_(2,3) 结果:3 |
| ior(a,b) | 即 a |= b | 按位或,原地运算符 | |
| xor(a,b) | a ^ b | 按位异或 | xor(2,3) 结果:1 |
| ixor(a,b) | a ^= b | 按位异或,原地运算符 | |

注解:(假设8位二进制,最高位为符号位,负数用补码形式存储)

① 按位取反。inv(2) 结果:-3

2(二进制:00000010):按位取反,则11111101(原码10000011,十进制:-3)。

② 左移。lshift(2,3) 结果:16

2(二进制:00000010):左移3位,则00010000(十进制:16)。

③ 按位与。and_(2,3) 结果:2

2(二进制:00000010),3(二进制:00000011):按位与,则00000010(十进制:2)。

按位与:1 & 1 = 1,1 & 0 = 0,0 & 0 = 0

按位或:1 | 1 = 1,1 | 0 = 1,0 | 0 = 0

按位异或:1 ^ 1 = 0,1 ^ 0 = 1,0 ^ 0 = 0

2、比较运算

|---------|---------|------|------------------|
| 函数 | 对应运算符 | 描述 | 举例 |
| lt(a,b) | a < b | 小于 | lt(2,3) 结果:True |
| le(a,b) | a <= b | 小于等于 | le(2,3) 结果:True |
| gt(a,b) | a > b | 大于 | gt(2,3) 结果:False |
| ge(a,b) | a >= b | 大于等于 | ge(2,3) 结果:False |
| eq(a,b) | a == b | 等于 | eq(2,3) 结果:False |
| ne(a,b) | a != b | 不等于 | ne(2,3) 结果:True |

lt:less than 小于

le:less than or equal to 小于等于

gt:greater than 大于

ge:greater than or equal to 大于等于

eq:equal to 等于

ne:not equal to 不等于​​​​​​​

3、逻辑运算

|-------------|------------|----------------------------|-------------------|
| 函数 | 对应运算符 | 描述 | 举例 |
| truth(a) | a | 真值测试。a 为真,返回True,否则返回False | truth(0) 结果:False |
| not_(a) | not a | 逻辑取反 | not_(0) 结果:True |
| is_(a,b) | a is b | a 是 b | |
| is_not(a,b) | a is not b | a 不是 b | |

4、序列运算

注意:原地运算符中被赋值的序列需是可变的。若不可变的序列(字符串、元组),会计算但不会赋值,即不改变原序列。

|----------------|------------|----------------------------|----------------------------------------------------------------------------------------------------------------------------|
| 函数 | 对应运算符 | 描述 | 举例 |
| concat(a,b) | a + b | 序列a、b,拼接 | concat([1],[2,3]) 结果:[1, 2, 3] |
| iconcat(a,b) | a += b | 序列a、b,拼接,原地运算符 | |
| contains(a,b) | b in a | 序列a 中包含元素b | contains("hello","e") 结果:True |
| countOf(a,b) | | 序列a 中元素b出现的次数 | countOf("hello","l") 结果:2 |
| indexOf(a,b) | | 序列a 中元素b第一次出现的位置。若不存在,则报错 | indexOf("hello","o") 结果:4 |
| getitem(a,b) | a[b] | 序列a 中获取下标/切片b对应的元素 | getitem("hello",1) 结果:'e' getitem("hello",slice(1,3)) 结果:'el' |
| setitem(a,b,c) | a[b]=c | 可变序列a 中赋值下标/切片b对应的元素为c | a = [1,2,3]; setitem(a,2,"w"); a 结果:[1, 2, 'w'] a = [1,2,3]; setitem(a,slice(1,3),["w","y"]); a 结果:[1, 'w', 'y'] |
| delitem(a,b) | del a[b] | 可变序列a 中删除下标/切片b对应的元素 | a = [1,2,3]; delitem(a,1); a 结果:[1, 3] a = [1,2,3]; delitem(a,slice(1,3)); a 结果:[1] |
| length_hint(a) | len(a) | 序列a的长度 | length_hint("hello") 结果:5 |

add 和 iadd 也可以拼接序列,和concat结果相同。

|-----------|--------|----------------|-----------------------------------|
| 函数 | 对应运算符 | 描述 | 举例 |
| add(a,b) | a + b | 序列a、b,拼接 | add([1],[2,3]) 结果:[1, 2, 3] |
| iadd(a,b) | a += b | 序列a、b,拼接,原地运算符 | |

5、3.11 新版功能

提供了快速访问对象的属性、获取序列元素、方法调用。

适合作为快速提取器(map, sorted, itertools**.**groupby等)的参数。

(5-1)attrgetter 【访问对象的属性】

  • attrgetter(属性)(对象):对象**.**属性,即获取对象的属性。
  • attrgetter(属性1, 属性2 ...)(对象):(对象**.** 属性1, 对象**.**属性2,...),即获取对象的多个属性,返回元组形式。
python 复制代码
from operator import *

class People(object):
    def __init__(self,name,age):
        self.name = name
        self.age = age

p1 = People("Tom",18)
p2 = People("Jack",25)

get_age = attrgetter("age")
get_age(p1)                                   # 结果:18
get_age(p2)                                   # 结果:25
# 相当于         
p1.age                                        # 结果:18
p2.age                                        # 结果:25
         
get_all = attrgetter("name","age")
get_all(p1)                                   # 结果:('Tom', 18)
get_all(p2)                                   # 结果:('Jack', 25)
# 相当于
p1.name,p1.age                                # 结果:('Tom', 18)
p2.name,p2.age                                # 结果:('Jack', 25)

# attrgetter 比 lambda 速度快
list(map(get_age,[p1,p2]))                    # 结果:[18, 25]
# 相当于
list(map(lambda x:x.age,[p1,p2]))             # 结果:[18, 25]

list(map(get_all,[p1,p2]))                    # 结果:[('Tom', 18), ('Jack', 25)]
# 相当于  
list(map(lambda x:(x.name,x.age),[p1,p2]))    # 结果:[('Tom', 18), ('Jack', 25)]

(5-2)itemgetter 【获取序列的元素】

  • itemgetter(下标)(序列):序列[下标],即获取序列中下标对应的元素。
  • itemgetter(slice(起始下标, 结束下标))(序列): 序列[起始下标**:**结束下标],通过切片获取序列中的元素。
  • itemgetter(下标1, 下标2, ...)(序列):(序列[下标1],序列[下标2],...),即获取序列中多个下标对应的元素,返回元组形式。
python 复制代码
from operator import *

a = "hello"
itemgetter(1)(a)                  # 结果:'e'
itemgetter(slice(1,4))(a)         # 结果:'ell'
itemgetter(1,2,4)(a)              # 结果:('e', 'l', 'o')
  • itemgetter(键)(字典):字典[键],通过键获取字典中的值。
  • itemgetter(键1, 键2,...)(字典):(字典[键1], 字典[键2], ...),通过多个键获取字典中的值,返回元组形式。
python 复制代码
from operator import *

d = {'一季度':20,'二季度':50,'三季度':15,'四季度':35}
itemgetter('二季度')(d)                     # 结果:50
itemgetter('二季度','四季度')(d)            # 结果:(50, 35)

在sorted、map等使用时,itemgetter 比 lambda 速度快。

python 复制代码
from operator import *

b = [("一季度",20),("二季度",50),("三季度",15),("四季度",35)]
# 按元组中下标为1的元素大小排序
sorted(b,key=itemgetter(1))       # 结果:[('三季度', 15), ('一季度', 20), ('四季度', 35), ('二季度', 50)]
# 相当于
sorted(b,key=lambda x:x[1])       # 结果:[('三季度', 15), ('一季度', 20), ('四季度', 35), ('二季度', 50)]

# 获取元组中下标为1的元素
list(map(itemgetter(1),b))        # 结果:[20, 50, 15, 35]
# 相当于
list(map(lambda x:x[1],b))        # 结果:[20, 50, 15, 35]

(5-3)methodcaller 【调用对象的方法】

  • methodcaller(方法)(对象):对象**.**方法(),即调用对象的方法。
  • methodcaller(方法, 参数1, 参数2 ...)(对象):对象**.**方法(参数1, 参数2,...),即调用对象的方法,并传递参数。
python 复制代码
from operator import *

class People(object):
    def __init__(self,name,age):
        self.name = name
        self.age = age

    def introduce(self):
        return f"我是{self.name}"

p1 = People("Tom",18)

intro = methodcaller("introduce")
intro(p1)                              # 结果:'我是Tom'
# 相当于
p1.introduce()                         # 结果:'我是Tom'
相关推荐
爱学习的Allan8 分钟前
使用 pyreqs 快速创建 requirements.txt & PyCharm 中 UnicodeDecodeError 问题
ide·python·pycharm·pip
代码小将24 分钟前
PTA数据结构编程题7-1最大子列和问题
数据结构·c++·笔记·学习·算法
HackKong29 分钟前
高校网络安全_网络安全之道
java·网络·c++·python·学习·web安全·黑客技术
annesede41 分钟前
计算机操作系统与安全复习笔记
笔记
滴_咕噜咕噜1 小时前
学习笔记 --C#基础其他知识点(持续更新)
笔记·学习·c#
yangjiwei02071 小时前
数据结构-排序
数据结构·python
秋天下着雨1 小时前
apifox调用jar程序
java·python·jar
bs_1011 小时前
【保姆式】python调用api通过机器人发送文件到飞书指定群聊
python·机器人·飞书
Redamancy_Xun2 小时前
软件老化分析
python·程序人生·安全威胁分析·可信计算技术·安全架构
geovindu2 小时前
python: Oracle Stored Procedure query table
数据库·python·mysql·postgresql·oracle·sqlserver·mssql