Почему я должен использовать operator.itemgetter(x) вместо [x]?
Здесь есть более общий вопрос: В какой ситуации должен использоваться встроенный модуль operator
в python?
Верхний ответ утверждает, что operator.itemgetter(x)
является "опрятным", чем, предположительно, чем lambda a: a[x]
. Я считаю, что обратное верно.
Есть ли другие преимущества, такие как производительность?
Ответы
Ответ 1
Вы не должны беспокоиться о производительности, если ваш код не находится в жестком внутреннем цикле и на самом деле является проблемой производительности. Вместо этого используйте код, который наилучшим образом выражает ваши намерения. Некоторым людям нравятся лямбды, некоторые вроде itemgetter. Иногда это просто вопрос вкуса.
itemgetter
более мощный, например, если вам нужно получить сразу несколько элементов. Например:
operator.itemgetter(1,3,5)
совпадает с:
lambda s: (s[1], s[3], s[5])
Ответ 2
В некоторых ситуациях есть преимущества, вот хороший пример.
>>> data = [('a',3),('b',2),('c',1)]
>>> from operator import itemgetter
>>> sorted(data, key=itemgetter(1))
[('c', 1), ('b', 2), ('a', 3)]
Это использование itemgetter
отлично, потому что оно делает все понятным, а также быстрее, поскольку все операции хранятся на стороне C
.
>>> sorted(data, key=lambda x:x[1])
[('c', 1), ('b', 2), ('a', 3)]
Использование lambda
не так ясно, оно также медленнее, и не рекомендуется использовать lambda
, если это необходимо. Например. список предпочтительнее использования map
с lambda
.
Ответ 3
Производительность. Это может иметь большое значение. В правильных обстоятельствах вы можете получить кучу вещей, сделанных на уровне C, используя itemgetter.
Я думаю, что утверждение о том, что яснее, действительно зависит от того, что вы используете чаще всего и было бы очень субъективным
Ответ 4
Некоторые программисты понимают и используют лямбда, но есть популяция программистов, которые, возможно, не занимались информатикой и не поняли эту концепцию. Для тех программистов itemgetter()
может сделать ваше намерение более ясным. (Я не пишу лямбды, и в любое время, когда я вижу один в коде, мне нужно немного времени, чтобы обработать то, что происходит и понять код).
Если ваше кодирование для других специалистов в области информатики идет вперед и использует лямбда, если они более удобны. Однако, если ваше кодирование для более широкой аудитории я предлагаю использовать itemgetter()
.
Ответ 5
Как было упомянуто о производительности, я сравнил оба метода operator.itemgetter
и lambda
, и для небольшого списка оказалось, что operator.itemgetter
превосходит лямбду по 10%
. Мне лично нравится метод itemgetter
, поскольку я в основном использую его во время сортировки, и он стал для меня ключевым словом.
import operator
import timeit
x = [[12, 'tall', 'blue', 1],
[2, 'short', 'red', 9],
[4, 'tall', 'blue', 13]]
def sortOperator():
x.sort(key=operator.itemgetter(1, 2))
def sortLambda():
x.sort(key=lambda x:(x[1], x[2]))
if __name__ == "__main__":
print(timeit.timeit(stmt="sortOperator()", setup="from __main__ import sortOperator", number=10**7))
print(timeit.timeit(stmt="sortLambda()", setup="from __main__ import sortLambda", number=10**7))
>>Tuple: 9.79s, Single: 8.835s
>>Tuple: 11.12s, Single: 9.26s
Запуск на Python 3.6
Ответ 6
Оставляя в стороне производительность и стиль кода, itemgetter
можно выбирать, а 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)
Ответ 7
При использовании этого параметра key
в sorted()
или min()
, учитывая выбор между, скажем, operator.itemgetter(1)
и lambda x: x[1]
, первый тип обычно значительно быстрее в обоих случаях:
Использование sorted()
![bm]()
Сравниваемые функции определяются следующим образом:
import operator
def sort_key_itemgetter(items, key=1):
return sorted(items, key=operator.itemgetter(key))
def sort_key_lambda(items, key=1):
return sorted(items, key=lambda x: x[key])
Результат: sort_key_itemgetter()
быстрее на ~ 10% до ~ 15%.
(Полный анализ здесь)
Использование min()
![enter image description here]()
Сравниваемые функции определяются следующим образом:
import operator
def min_key_itemgetter(items, key=1):
return min(items, key=operator.itemgetter(key))
def min_key_lambda(items, key=1):
return min(items, key=lambda x: x[key])
Результат: min_key_itemgetter()
быстрее на ~ 20% до ~ 60%.
(Полный анализ здесь)