В какой ситуации должен использоваться встроенный модуль "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
?" Ответы:
-
operator.add
(я думаю) немного быстрее. - Это делает код более легким для понимания для вас или другого человека, изучающего его позже. Им не нужно искать определение add, потому что они знают, что делает модуль оператора.
-
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)
Таким образом, избегая необходимости создавать лямбда-выражения.