内置的';操作员';模块在python中可以使用吗?

内置的';操作员';模块在python中可以使用吗?,python,operators,Python,Operators,我说的是这个模块: 从文章中: 操作员模块导出一组数据 用C语言实现的函数 对应于内在的 Python的运算符。例如 运算符.add(x,y)等价于 表达式x+y。函数名 那些是用来上特殊课的吗 方法;无前导和后导的变体 还提供了用于 方便 我不确定我是否理解此模块的好处或用途。一个例子是使用reduce()函数: >>> import operator >>> a = [2, 3, 4, 5] >>> reduce(lambda x, y

我说的是这个模块:

从文章中:

操作员模块导出一组数据 用C语言实现的函数 对应于内在的 Python的运算符。例如 运算符.add(x,y)等价于 表达式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这里的关键短语是--“当您需要将函数作为参数传递给某个对象时,模块非常有用”。我想不出使用该模块的任何其他原因。