在什么情况下应该在python中使用内置的“运算符”模块?

时间:2009-01-22 03:03:47

标签: python operators

我说的是这个模块: http://docs.python.org/library/operator.html

来自文章:

  

运算符模块导出一组   用C实现的函数   对应于内在的   Python的运算符。例如,   operator.add(x,y)等价于   表达式x + y。功能名称   是用于特殊课程的那些   方法;变种没有领先和   尾随__也提供   便利性。

我不确定我理解这个模块的好处或目的。

6 个答案:

答案 0 :(得分:37)

最常用的可能是operator.itemgetter。给定元组的列表lst,您可以按第i个元素排序:lst.sort(key=operator.itemgetter(i))

当然,你可以通过定义自己的键功能来做同样的事情而不需要操作员,但是操作员模块使它稍微整洁。

至于其余部分,python允许一种功能性的编程风格,因此它可以出现 - 例如,Greg的简化示例。

您可能会争辩说:“为什么我可以做operator.add时需要add = lambda x, y: x+y?”答案是:

  1. operator.add(我认为)稍快一些。
  2. 它使代码更易于理解,或者让其他人稍后再去理解它。他们不需要查找add的定义,因为他们知道运算符模块的作用。
  3. operator.add是可挑选的,而lambda则不是。这意味着该函数可以保存到磁盘或在进程之间传递。

答案 1 :(得分:25)

一个例子是使用reduce()函数:

>>> import operator
>>> a = [2, 3, 4, 5]
>>> reduce(lambda x, y: x + y, a)
14
>>> reduce(operator.add, a)
14

答案 2 :(得分:3)

例如,

获取列表中的列,其成员为元组,按列排序:

$tabs = $_POST;

看一个更实际的例子,我们想按键或值对dict进行排序:

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)]

当我们想要获取列表中的最大值及其索引时的另一个示例:

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

python doc

了解详情

答案 3 :(得分:2)

当您需要将函数作为参数传递给某些东西时,该模块很有用。然后有两个选项:使用operator模块,或定义新功能(使用deflambda)。如果你动态定义一个函数,如果你需要pickle这个函数,这可能会产生一个问题,要么将它保存到磁盘或在进程之间传递它。虽然itemgetter是可选择的,但动态定义的函数(deflambda)不是。在以下示例中,将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)

答案 4 :(得分:0)

通常,此模块的目的(如上面的某些答案所暗示)是为您提供固定功能,以进行简单的操作,否则您必须自己编写并传递给高阶函数,例如{ {1}}或sort()

例如,没有运算符,要对列表中的数字求和,您将必须执行以下操作:

reduce()

通过运算符模块,您可以像这样使用其from functools import reduce l = list(range(100)) f = lambda x, y: x + y result = reduce(f, l) print(result) 函数:

add()

因此避免了创建lambda表达式的需要。

答案 5 :(得分:0)

我不记得确切的用例,但是我有一个需要动态进行一些计算的地方,这可能要根据其来源使用不同的运算符。

一个非常简单的例子是

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)