În ce situație ar trebui utilizat modulul built-in „operator” în python? (Programare, Python, Operatori)

Mă refer la acest modul:http://docs.python.org/library/operator.html

Din articol:

Modulul operator exportă un set de funcții implementate în C care corespund operatorilor intrinseci din Python. De exemplu, operator.add(x, y) este echivalent cu expresia x+y. Numele funcțiilor sunt cele utilizate pentru metodele din clasele speciale; pentru comoditate, sunt furnizate și variante fără __ de început și de sfârșit.

Nu sunt sigur că înțeleg beneficiul sau scopul acestui modul.

Comentarii

  • Acest modul mi se pare cam prostesc. Tot ce pot face cu el sunt lucruri pe care le pot face cu ușurință și fără el. Pare a fi o încălcare clară a unuia dintre principiile din Zen al Python: „Ar trebui să existe o – și, de preferință, numai una – modalitate evidentă de a face asta.” –  > Por Elias Zamaria.
6 răspunsuri

Posibil cea mai populară utilizare este operator.itemgetter. Având în vedere o listă lst de tupluri, puteți sorta după al i-lea element prin: lst.sort(key=operator.itemgetter(i))

Desigur, ai putea face același lucru fără operator definind propria funcție cheie, dar modulul operator face lucrurile ceva mai ordonate.

În rest, python permite un stil funcțional de programare, așa că poate apărea – de exemplu, exemplul de reducere al lui Greg.

Ați putea argumenta: „De ce am nevoie de operator.add când pot să fac pur și simplu: add = lambda x, y: x+y?” Răspunsurile sunt:

  1. operator.add este (cred) puțin mai rapid.
  2. Face codul mai ușor de înțeles pentru tine sau pentru o altă persoană care îl examinează mai târziu. Aceștia nu trebuie să caute definiția lui add, pentru că știu ce face modulul operator.
  3. operator.add este decapabil, în timp ce lambda nu este. Acest lucru înseamnă că funcția poate fi salvată pe disc sau transmisă între procese.

Comentarii

  • operator.add este mai rapidă”: Se pare că nu este: $ python -m timeit "5 + 8" 100000000 loops, best of 3: 0.016 usec per loop $ python -m timeit -s "from operator import add" "add(5, 8)" 10000000 loops, best of 3: 0.0628 usec per loop –  > Por Marco Sulla.
  • @MarcoSulla Nu spun că operator.add(5,8) este mai rapid decât 5+8. Spun că eu cred că este mai rapid decât (lambda x,y: x+y)(5,8)(5,8) –  > Por John Fouhy.
  • Bine prins: $ python -m timeit "(lambda x,y: x+y)(5,8)" 10000000 bucle, cel mai bun din 3: 0,127 usec pe buclă. $ python -m timeit -s "from operator import add" "add(5,8)" 10000000 bucle, cel mai bun din 3: 0,0614 usec pe buclă –  > Por Marco Sulla.
  • Eu folosesc itemgetter și este încă util în python 3.6, și rapid –  > Por ragardner.

Un exemplu este în utilizarea reduce() funcției:

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

Modulul este util atunci când trebuie să treceți o funcție ca argument pentru ceva. Există atunci două opțiuni: utilizați funcția operator sau definiți o nouă funcție (utilizând def sau lambda). Dacă definiți o funcție din mers, acest lucru poate crea o problemă dacă aveți nevoie să o păstrați, fie pentru a o salva pe disc, fie pentru a o transmite între procese. În timp ce itemgetter este decapabilă, funcțiile definite dinamic (fie cu def fie lambda) nu sunt. În exemplul următor, înlocuirea itemgetter cu un lambda va avea ca rezultat o expresie 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)

Comentarii

  • Fraza cheie aici este următoarea — „Modulul este util atunci când trebuie să treceți o funcție ca argument la ceva”. Nu mă pot gândi la niciun alt motiv pentru a folosi modulul. –  > Por Jarmos.

de exemplu, obțineți coloana dintr-o listă al cărei membru este un tuple, sortați secvența după coloană:

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

vedeți un exemplu mai practic, dorim să sortăm un dict după cheie sau după valoare:

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

un alt exemplu când dorim să obținem valoarea maximă și indicele acesteia în listă:

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

Mai multe demonstrații ca cele de mai jos:

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

vezi mai multe din python doc

Comentarii

  • +1 pentru exemplul argmax. Am regretat adesea lipsa funcțiilor încorporate argmax și argmin în python. –  > Por saulspatz.
  • Grozav post, Jayhello –  > Por Jon.

În general, scopul acestui modul (așa cum se face aluzie la unele dintre răspunsurile de mai sus) este de a vă oferi funcții conservate pentru operații simple pe care, altfel, ar trebui să le scrieți singur și să le transmiteți unor funcții de ordin superior, cum ar fi sort() sau reduce().

De exemplu, fără operatori, pentru a aduna numerele dintr-o listă, ar trebui să faceți ceva de genul acesta:

from functools import reduce

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

Cu ajutorul modulului operator, ați putea utiliza funcția add() în felul următor:

from operator import add

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

Astfel, se evită necesitatea de a crea o expresie lambda.

Nu-mi amintesc exact cazul de utilizare, dar am avut undeva o cerință care trebuia să facă un calcul dinamic și acesta putea folosi un operator diferit în funcție de locul de unde provenea.

Un exemplu foarte simplu este următorul:

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)