-
itemgetter:
当你想通过索引选择元素时使用这个:
from operator import itemgetter
numbers = [[0, 1, 2, 3],
[4, 5, 6, 7],
[8, 9, 0, 1]]
result_1 = map(lambda x: x[0], numbers)
result_2 = (x[0] for x in numbers)
result_3 = map(itemgetter(0), numbers)
# [0, 4, 8]
虽然它比给定示例中的生成器表达式长,但当您想一次选择多个元素时,它实际上会更短:
result_1 = map(lambda x: (x[0], x[2], x[3]), numbers)
result_2 = ((x[0], x[2], x[3]) for x in numbers)
result_3 = map(itemgetter(0, 2, 3), numbers)
# [(0, 2, 3), (4, 6, 7), (8, 0, 1)]
您也可以将itemgetter 与字典一起使用:
data = [{'time': 0, 'temperature': 290, 'pressure': 1.01},
{'time': 10, 'temperature': 295, 'pressure': 1.04},
{'time': 20, 'temperature': 300, 'pressure': 1.07}]
result_1 = map(lambda x: (x['time'], x['pressure']), data)
result_2 = ((x['time'], x['pressure']) for x in data)
result_3 = map(itemgetter('time', 'pressure'), data)
# [(0, 1.01), (10, 1.04), (20, 1.07)]
-
attrgetter
这个是用来获取对象属性的:
from collections import namedtuple
from operator import attrgetter
Person = namedtuple('Person', ['name', 'surname', 'age', 'car'])
people = [Person(name='John', surname='Smith', age=40, car='Tesla'),
Person(name='Mike', surname='Smith', age=50, car=None)]
result_1 = map(lambda x: (x.name, x.age, x.car), people)
result_2 = ((x.name, x.age, x.car) for x in people)
result_3 = map(attrgetter('name', 'age', 'car'), people)
# [('John', 40, 'Tesla'), ('Mike', 50, None)]
它比生成器表达式版本长,所以我把它留在这里只是为了完整。当然,您可以将attrgetter 导入为get,它会更短,但没有人真正这样做。不过,使用attrgetter 有一个优势,您可以将其作为单独的可调用对象取出,可以多次使用(与lambda 相同):
get_features = attrgetter('name', 'age', 'car')
group_1_features = map(get_features, people)
group_2_features = map(get_features, other_people)
...
另一个值得一提的替代方法是使用 fget 属性方法:
result = map(Person.age.fget, people)
不过,我从未见过有人使用它,因此请准备好向那些在您使用它时会阅读您的代码的人进行解释。
-
contains:
用于检查一个元素是否存在于另一个对象/容器中:
from functools import partial
from operator import contains
fruits = {'apple', 'peach', 'orange'}
objects = ['apple', 'table', 'orange']
result_1 = map(lambda x: x in fruits, objects)
result_2 = (x in fruits for x in objects)
is_fruit = partial(contains, fruits)
result_3 = map(is_fruit, objects)
# [True, False, True]
不过,这有一个缺点,就是创建了一个额外的partial 对象。另一种写法是使用__contains__ 方法:
result = map(fruits.__contains__, objects)
但有些人认为使用 dunder 方法是一种不好的做法,因为这些方法仅供私人使用。
-
数学运算:
例如,如果您想对数对求和,可以使用operator.add:
from itertools import starmap
from operator import add
pairs = [(1, 2), (4, 3), (1, 10), (2, 5)]
result_1 = map(lambda x: x[0] + x[1], pairs)
result_2 = (x + y for x, y in pairs)
result_3 = starmap(add, pairs)
# [3, 7, 11, 7]
如果您对两个额外的导入没问题,那么这是最短的选择。请注意,我们在这里使用itertools.starmap,因为我们需要在将数字元组提供给add(a, b) 函数之前对其进行解包。