内置的';操作员';模块在python中可以使用吗?
我说的是这个模块: 从文章中: 操作员模块导出一组数据 用C语言实现的函数 对应于内在的 Python的运算符。例如 运算符.add(x,y)等价于 表达式x+y。函数名 那些是用来上特殊课的吗 方法;无前导和后导的变体 还提供了用于 方便内置的';操作员';模块在python中可以使用吗?,python,operators,Python,Operators,我说的是这个模块: 从文章中: 操作员模块导出一组数据 用C语言实现的函数 对应于内在的 Python的运算符。例如 运算符.add(x,y)等价于 表达式x+y。函数名 那些是用来上特殊课的吗 方法;无前导和后导的变体 还提供了用于 方便 我不确定我是否理解此模块的好处或用途。一个例子是使用reduce()函数: >>> import operator >>> a = [2, 3, 4, 5] >>> reduce(lambda x, y
我不确定我是否理解此模块的好处或用途。一个例子是使用
reduce()
函数:
>>> import operator
>>> a = [2, 3, 4, 5]
>>> reduce(lambda x, y: x + y, a)
14
>>> reduce(operator.add, a)
14
最常用的用法可能是operator.itemgetter。给定一个元组列表
lst
,您可以通过以下方式按第i个元素排序:lst.sort(key=operator.itemgetter(i))
当然,通过定义自己的键函数,您可以在没有操作符的情况下完成同样的事情,但是操作符模块使它稍微整洁一些
至于其余部分,python允许函数式编程,因此它可以出现——例如,Greg的reduce示例
你可能会说:“为什么我需要操作符。当我能做的时候添加:add=lambda x,y:x+y
?”答案是:
operator.add(我认为)稍微快一点
它使代码更容易为您或其他人理解。他们不需要查找add的定义,因为他们知道operator模块做什么
operator.add
可拾取,而lambda
不可拾取。这意味着该函数可以保存到磁盘或在进程之间传递
当您需要将函数作为参数传递给某个对象时,该模块非常有用。然后有两个选项:使用操作员
模块,或定义新功能(使用def
或lambda
)。如果动态定义一个函数,如果需要对该函数进行pickle(将其保存到磁盘或在进程之间传递),则可能会产生问题。虽然itemgetter
是可拾取的,但动态定义的函数(使用def
或lambda
)不是可拾取的。在以下示例中,将itemgetter
替换为lambda
表达式将导致PicklingError
from operator import itemgetter
def sort_by_key(sequence, key):
return sorted(sequence, key=key)
if __name__ == "__main__":
from multiprocessing import Pool
items = [([(1,2),(4,1)], itemgetter(1)),
([(5,3),(2,7)], itemgetter(0))]
with Pool(5) as p:
result = p.starmap(sort_by_key, items)
print(result)
例如,获取列表中成员为元组的列,按列排序:
def item_ope():
s = ['h', 'e', 'l', 'l', 'o']
print operator.getitem(s, 1)
# e
print operator.itemgetter(1, 4)(s)
# ('e', 'o')
inventory = [('apple', 3), ('banana', 2), ('pear', 5), ('orange', 1)]
get_count = operator.itemgetter(1)
print map(get_count, inventory)
# [3, 2, 5, 1]
print sorted(inventory, key=get_count)
# [('orange', 1), ('banana', 2), ('apple', 3), ('pear', 5)]
请参阅更实际的示例,我们希望按键或值对dict进行排序:
def dict_sort_by_value():
dic_num = {'first': 11, 'second': 2, 'third': 33, 'Fourth': 4}
# print all the keys
print dic_num.keys()
# ['second', 'Fourth', 'third', 'first']
# sorted by value
sorted_val = sorted(dic_num.items(), key=operator.itemgetter(1))
# [('second', 2), ('Fourth', 4), ('first', 11), ('third', 33)]
print sorted_val
# sorted by key
sorted_key = sorted(dic_num.items(), key=operator.itemgetter(0))
print sorted_key
# [('Fourth', 4), ('first', 11), ('second', 2), ('third', 33)]
另一个示例是,当我们想要获取最大值及其在列表中的索引时:
def get_max_val_idx():
lst = [1, 7, 3, 5, 6]
max_val = max(lst)
print max_val
# 7
max_idx = lst.index(max_val)
print max_idx
# 1
# simplify it by use operator
index, value = max(enumerate(lst), key=operator.itemgetter(1))
print index, value
# 1 7
更多演示如下:
import operator
def cmp_fun():
a, b = 5, 3
print operator.le(a, b)
# False
print operator.gt(a, b)
# True
def lst_ope():
lst = [1, 2, 3]
print operator.indexOf(lst, 2)
# 1
lst1 = [1, 2, 3, 2]
print operator.countOf(lst1, 2)
# 2
def cal_ope():
lst1 = [0, 1, 2, 3]
lst2 = [10, 20, 30, 40]
print map(operator.mul, lst1, lst2)
# [0, 20, 60, 120]
print sum(map(operator.mul, lst1, lst2))
# 200
a, b = 1, 3
print operator.iadd(a, b)
# 4
参见一般来说,本模块的目的(正如上面一些答案所提到的)是为您提供一些固定函数,用于简单的操作,否则您必须自己编写并传递给更高阶的函数,如sort()
或reduce()
例如,如果没有运算符,要对列表中的数字求和,必须执行以下操作:
from functools import reduce
l = list(range(100))
f = lambda x, y: x + y
result = reduce(f, l)
print(result)
from operator import add
result = reduce(add, l)
print(result)
使用操作员模块,您可以使用其add()
函数,如下所示:
from functools import reduce
l = list(range(100))
f = lambda x, y: x + y
result = reduce(f, l)
print(result)
from operator import add
result = reduce(add, l)
print(result)
这样就避免了创建lambda表达式的需要。我记不起确切的用例,但我有一个需求,需要动态地进行一些计算,这可能是使用不同的运算符,具体取决于它来自何处
一个非常简单的例子是:
import operator
def add_or_subtract(x, y, op):
return op(x, y)
x = 3
y = 10
o = operator.add #operator.sub
add_or_subtract(x, y, o)
我觉得这个模块有点傻。我能用它做的就是不用它我可以轻松做的事情。这似乎明显违反了“应该有一种——最好只有一种——显而易见的方法来做。”“operator.add
更快”:似乎不是:$python-m timeit“5+8”100000000个循环,最好是3:0.016 usec per loop$python-m timeit-s”from operator import add”“add(5,8)”10000000个循环,最好是3:0.0628 usec/循环
@MarcoSulla我不是说运算符。加法(5,8)比5+8快。我是说,我认为它比(lambda x,y:x+y)(5,8)快得多:$python-m timeit”(lambda x,y:x+y)(5,8)”
10000000个循环,每个循环最好3:0.127 usec$python-m timeit-s“从操作符导入添加”“添加(5,8)”
10000000个循环,每个循环最好3:0.0614 usec我使用itemgetter,它在python 3.6中仍然很有用,对于argmax示例,quick too+1。我经常对python中缺少内置的argmax和argmin函数感到遗憾。很棒的帖子,Jayhelloth这里的关键短语是--“当您需要将函数作为参数传递给某个对象时,模块非常有用”。我想不出使用该模块的任何其他原因。