本模块主要包括一些Python内部操作符对应的函数。这些函数主要分为几类:对象比较、逻辑比较、算术运算和序列操作。
操作 |
语法 |
函数 |
相加 |
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 is b |
is_(a, b) |
识别 |
a is not 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 |
neg(a) |
非运算 |
not a |
not_(a) |
正数 |
+ a |
pos(a) |
右移运算 |
a >> b |
rshift(a, b) |
切片赋值 |
seq[i:j] = values |
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) |
operator的使用
attrgetter
operator.attrgetter(attr)和operator.attrgetter(*attrs)
- After f = attrgetter(‘name’), the call f(b) returns b.name.
- After f = attrgetter(‘name’, ‘date’), the call f(b) returns (b.name, b.date).
- After f = attrgetter(‘name.first’, ‘name.last’), the call f(b) returns (b.name.first, b.name.last).
我们通过下面这个例子来了解一下itergetter的用法:
>>> class Student:
... def __init__(self, name, grade, age):
... self.name = name
... self.grade = grade
... self.age = age
... def __repr__(self):
... return repr((self.name, self.grade, self.age))
>>> student_objects = [
... Student('john', 'A', 15),
... Student('jane', 'B', 12),
... Student('dave', 'B', 10),
... ]
>>> sorted(student_objects, key=lambda student: student.age) # 传统的lambda做法
[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
>>> from operator import itemgetter, attrgetter
>>> sorted(student_objects, key=attrgetter('age'))
[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
# 但是如果像下面这样接受双重比较,Python脆弱的lambda就不适用了
>>> sorted(student_objects, key=attrgetter('grade', 'age'))
[('john', 'A', 15), ('dave', 'B', 10), ('jane', 'B', 12)]
attrgetter的实现原理:
def attrgetter(*items):
if any(not isinstance(item, str) for item in items):
raise TypeError('attribute name must be a string')
if len(items) == 1:
attr = items[0]
def g(obj):
return resolve_attr(obj, attr)
else:
def g(obj):
return tuple(resolve_attr(obj, attr) for attr in items)
return g
def resolve_attr(obj, attr):
for name in attr.split("."):
obj = getattr(obj, name)
return obj
attritem
提取对象的属性。
attritem
和itemgetter
相似 namedtuple
是tuple
的子集。提供了一个类似元祖的数据结构,并声明空的属性。
collections.namedtuple(typename, field_names, *, rename=False, defaults=None, module=None)
两者的关系相当于下标用字符串和数字去访问。
>>> from collections import namedtuple
>>> LatLong = namedtuple('LatLong', 'lat long') # 定义 LatLong
>>> Metropolis = namedtuple('Metropolis', 'name cc pop coord') # 再定义 Metropolis
>>> metro_areas = [Metropolis(name, cc, pop, LatLong(lat, long)) # 使用嵌套的元组拆包提取 (lat, long)
... for name, cc, pop, (lat, long) in metro_data]
>>> metro_areas[0]
Metropolis(name='Tokyo', cc='JP', pop=36.933, coord=LatLong(lat=35.689722,
long=139.691667))
>>> metro_areas[0].coord.lat # 深入 metro_areas[0],获取它的纬度。
35.689722
>>> from operator import attrgetter
>>> name_lat = attrgetter('name', 'coord.lat') # 定义一个 attrgetter,获取 name 属性和嵌套的 coord.lat 属性。
>>>
>>> for city in sorted(metro_areas, key=attrgetter('coord.lat')): # 使用 attrgetter,按照纬度排序城市列表。
... print(name_lat(city)) # 使用定义的 attrgetter city,只显示城市名和纬度。
...
('Sao Paulo', -23.547778)
('Mexico City', 19.433333)
('Delhi NCR', 28.613889)
('Tokyo', 35.689722)
('New York-Newark', 40.808611)
itemgetter
operator.itemgetter(item)和operator.itemgetter(*items)
- After f = itemgetter(2), the call f(r) returns r[2].
- After g = itemgetter(2, 5, 3), the call g(r) returns (r[2], r[5], r[3]).
我们通过下面这个例子来了解一下itergetter的用法:
>>> student_tuples = [
... ('john', 'A', 15),
... ('jane', 'B', 12),
... ('dave', 'B', 10),
... ]
>>> sorted(student_tuples, key=lambda student: student[2]) # 传统的lambda做法
[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
>>> from operator import attrgetter
>>> sorted(student_tuples, key=itemgetter(2))
[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
# 但是如果像下面这样接受双重比较,Python脆弱的lambda就不适用了
>>> sorted(student_tuples, key=itemgetter(1,2))
[('john', 'A', 15), ('dave', 'B', 10), ('jane', 'B', 12)]
itemgetter的实现原理
def itemgetter(*items):
if len(items) == 1:
item = items[0]
def g(obj):
return obj[item]
else:
def g(obj):
return tuple(obj[item] for item in items)
return g
使用 itemgetter
排序一个元组列表。
itemgetter(num) 指定一个位置。
>>> metro_data = [
... ('Tokyo', 'JP', 36.933, (35.689722, 139.691667)),
... ('Delhi NCR', 'IN', 21.935, (28.613889, 77.208889)),
... ('Mexico City', 'MX', 20.142, (19.433333, -99.133333)),
... ('New York-Newark', 'US', 20.104, (40.808611, -74.020386)),
... ('Sao Paulo', 'BR', 19.649, (-23.547778, -46.635833)),
... ]
>>>
>>> from operator import itemgetter
>>> for city in sorted(metro_data, key=itemgetter(1)):
... print(city)
...
('Sao Paulo', 'BR', 19.649, (-23.547778, -46.635833))
('Delhi NCR', 'IN', 21.935, (28.613889, 77.208889))
('Tokyo', 'JP', 36.933, (35.689722, 139.691667))
('Mexico City', 'MX', 20.142, (19.433333, -99.133333))
('New York-Newark', 'US', 20.104, (40.808611, -74.020386))
>>> cc_name = itemgetter(1, 0)
>>> for city in metro_data:
... print(cc_name(city))
...
('JP', 'Tokyo')
('IN', 'Delhi NCR')
('MX', 'Mexico City')
('US', 'New York-Newark')
('BR', 'Sao Paulo')
methodcaller
operator.methodcaller(name[, args…])
- After f = methodcaller(‘name’), the call f(b) returns b.name().
- After f = methodcaller(‘name’, ‘foo’, bar=1), the call f(b) returns b.name(‘foo’, bar=1).
methodcaller的实现原理:
def methodcaller(name, *args, **kwargs):
def caller(obj):
return getattr(obj, name)(*args, **kwargs)
return caller