В какой ситуации должен использоваться встроенный модуль "operator" в python?

Я говорю об этом модуле: http://docs.python.org/library/operator.html

Из статьи:

Модуль оператора экспортирует набор функции, реализованные в C соответствующей внутреннему операторов Python. Например, operator.add(x, y) эквивалентен выражение x + y. Названия функций те, которые используются для специального класса методы; варианты без ведущих и задние __ также предусмотрены для удобство.

Я не уверен, что понимаю преимущества или цели этого модуля.

Ответ 1

Возможно, самое популярное использование - operator.itemgetter. Имея список lst из кортежей, вы можете отсортировать по i-му элементу следующим образом: lst.sort(key=operator.itemgetter(i))

Конечно, вы могли бы сделать то же самое без оператора, определив свою собственную ключевую функцию, но модуль оператора делает ее немного аккуратнее.

В остальном, python допускает функциональный стиль программирования, и поэтому он может придумать - например, Грег привести пример.

Вы можете возразить: "Зачем мне нужен operator.add когда я могу просто сделать: add = lambda x, y: x+y?" Ответы:

  1. operator.add (я думаю) немного быстрее.
  2. Это делает код более легким для понимания для вас или другого человека, изучающего его позже. Им не нужно искать определение add, потому что они знают, что делает модуль оператора.
  3. operator.add доступен для захвата, а lambda - нет. Это означает, что функция может быть сохранена на диск или передана между процессами.

Ответ 2

Один пример заключается в использовании функции reduce():

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

Ответ 3

например, получить столбец в списке, членом которого является кортеж, отсортировать последовательность по столбцу:

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

Больше демо, как показано ниже:

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

увидеть больше от Python Doc

Ответ 4

Модуль полезен, когда вам нужно передать функцию в качестве аргумента. Затем есть два варианта: используйте модуль operator или определите новую функцию (используя def или lambda). Если вы определите функцию "на лету", это может создать проблему, если вам нужно разборки этой функции, либо сохранить ее на диск, либо передать ее между процессами. В то время как itemgetter является picklable, динамически определенные функции (либо с 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)

Ответ 5

В целом, цель этого модуля (на который ссылаются некоторые ответы выше) состоит в том, чтобы предоставить вам стандартные функции для простых операций, которые в противном случае вам пришлось бы писать самостоятельно, и переходить к функциям более высокого порядка, таким как sort() или reduce().

Например, без операторов для суммирования чисел в списке вы должны сделать что-то вроде этого:

from functools import reduce

l = list(range(100))
f = lambda x, y: x + y
result = reduce(f, l)
print(result)

С операторским модулем вы можете использовать его функцию add() следующим образом:

from operator import add

result = reduce(add, l)
print(result)

Таким образом, избегая необходимости создавать лямбда-выражения.