Kodėl naudinga python lambdas?

Bandau išsiaiškinti Python lambdas. Ar lambda yra vienas iš tų „įdomių“ kalbų dalykų, kuriuos reikia pamiršti realiame gyvenime?

Esu tikras, kad yra keletas ekstremalių atvejų, kai tai gali būti reikalinga, bet atsižvelgiant į jo dviprasmiškumą, potencialą jį iš naujo apibrėžti būsimuose leidiniuose (mano prielaida, pagrįsta įvairiomis jo apibrėžtimis) ir mažesnį kodavimo aiškumą - jei tai būtų išvengta?

Tai man primena C tipų perpildymą (buferio perpildymą) - viršutinio kintamojo rodiklį ir perkrovą nustatant kitas lauko reikšmes. Jis jaučiasi kaip meistriškumo klasė, bet palaikomasis koduotojas košmaras.

826
20 мая '09 в 23:40 2009-05-20 23:40 „ Meade“ gegužės 20 d., 09:40, 2009-05-20 23:40
@ 26 atsakymai

Ar kalbate apie lambda funkcijas ? Kaip

 lambda x: x**2 + 2*x - 5 

Šie dalykai iš tikrųjų yra gana naudingi. „Python“ palaiko programavimo stilių, vadinamą funkciniu programavimu, kur galite perduoti funkcijas kitoms funkcijoms. Pavyzdys:

 mult3 = filter(lambda x: x % 3 == 0, [1, 2, 3, 4, 5, 6, 7, 8, 9]) 

nustato [3, 6, 9] mult3 [3, 6, 9] tuos pradinio sąrašo elementus, kurie yra 3 kartotiniai. Tai trumpesnis (ir galima teigti, aiškiau) nei

 def filterfunc(x): return x % 3 == 0 mult3 = filter(filterfunc, [1, 2, 3, 4, 5, 6, 7, 8, 9]) 

Žinoma, šiuo konkrečiu atveju galėtumėte padaryti tą patį, kaip suprasti sąrašą:

 mult3 = [x for x in [1, 2, 3, 4, 5, 6, 7, 8, 9] if x % 3 == 0] 

(arba net kaip range(3,10,3) ), tačiau yra daug kitų, sudėtingesnių naudojimo atvejų, kai negalite naudoti sąrašo įžvalgos, o lambda funkcija gali būti trumpiausias būdas ką nors parašyti.

  • Grąžinkite funkciją iš kitos funkcijos

     >>> def transform(n): ... return lambda x: x + n ... >>> f = transform(3) >>> f(4) 7 

    Tai dažnai naudojama funkciniams apvalkalams, pvz., „Python“ dekoratoriams sukurti.

  • Iteracinės sekos elementų derinimas su reduce()

     >>> reduce(lambda a, b: '{}, {}'.format(a, b), [1, 2, 3, 4, 5, 6, 7, 8, 9]) '1, 2, 3, 4, 5, 6, 7, 8, 9' 
  • Rūšiuoti pagal alternatyvų raktą

     >>> sorted([1, 2, 3, 4, 5, 6, 7, 8, 9], key=lambda x: abs(5-x)) [5, 4, 6, 3, 7, 2, 8, 1, 9] 

Aš reguliariai naudojasi lambda funkcijomis. Prireikė šiek tiek laiko priprasti prie jų, bet galiausiai supratau, kad jie yra labai vertinga kalbos dalis.

902
20 мая '09 в 23:52 2009-05-20 23:52 Atsakymą davė David Z , gegužės 20 d., 09:23, 2009-05-20 23:52

lambda yra tik išgalvotas būdas pasakyti function . Be pavadinimo, nėra nieko paslėpto, bauginančio ar paslaptingo. Perskaitę šią eilutę, pakeiskite „ lambda su savo proto function :

 >>> f = lambda x: x + 1 >>> f(3) 4 

Jis tiesiog apibrėžia funkciją x . Kai kurios kitos kalbos, pvz., R , tai aiškiai nurodo:

border=0
 > f = function(x) { x + 1 } > f(3) 4 

Ar matote Tai vienas iš natūraliausių dalykų programuojant.

329
16 янв. Atsakymą pateikė user251650 Jan 16 2010-01-16 18:03 '10, 18:03, 2010-01-16 18:03

Dvi eilutės santrauka:

  • Uždarymas : labai naudinga. Ištirkite juos, naudokitės jais.
  • Python lambda raktinis žodis: nereikalingas, kartais naudingas. Jei radote sau ką nors su juo nuotoliniu būdu, nustatykite jį ir nustatykite faktinę funkciją.
94
21 мая '09 в 1:37 2009-05-21 01:37 atsakė Johnui Fouhiui gegužės 09 d. 1:37 2009-05-21 01:37

Lambda yra labai svarbios abstrakcijos mechanizmo dalis, susijusi su aukštesnės kategorijos funkcijomis. Norėdami gauti tinkamą jo vertės supratimą, žr. Abelsono ir Susmano aukštos kokybės pamokas ir perskaitykite SICP knygą .

Tai tikros problemos šiuolaikinėje programinės įrangos versle ir tampa vis populiaresnės.

71
20 мая '09 в 23:49 2009-05-20 23:49 atsakymas pateiktas egagoje gegužės 20 d. , 09:49 , 2009-05-20 23:49

Aš abejoju, kad lambda išnyks. Žr. Guido postą, kad galiausiai atsisakyta bandymo jį pašalinti. Taip pat žr. Kontūro konfliktą .

Šį įrašą galite rasti išsamesnės informacijos apie „Python“ funkcionalumo sandorį: http://python-history.blogspot.com/2009/04/origins-of-pythons-functional-features.html

Įdomu, kad rodymo, filtravimo ir mažinimo funkcijos, kurios iš pradžių paskatino įdiegti lambda ir kitas funkcines funkcijas, buvo iš esmės pakeistos generatoriaus sąrašų ir išraiškų išraiška. Iš tiesų, „Python 3.0“ integruotų funkcijų sąraše buvo pašalinta nuoroda. (Tačiau nereikia siųsti skundų dėl lambda, žemėlapio ar filtro pašalinimo: jie lieka.:)

Mano du centai: retai lambda yra verta, kaip aišku. Paprastai yra aiškesnis sprendimas, kuriame nėra lambda.

57
20 мая '09 в 23:46 2009-05-20 23:46 atsakymas pateikiamas „ Rhettg“ gegužės 20 d., 23:46, 2009-05-20 23:46

lambdas yra labai naudingi GUI programavimui. Pvz., Tarkime, kad sukuriate mygtukų grupę ir norite naudoti vieną parametrinį atšaukimą, o ne unikalų kiekvienos mygtuko atgalinio atšaukimo funkciją. „Lambda“ leidžia lengvai valdyti:

 for value in ["one","two","three"]: b = tk.Button(label=value, command=lambda arg=value: my_callback(arg)) b.pack() 

(Pastaba: nors šis klausimas konkrečiai užduoda klausimą apie lambda , taip pat galite naudoti functools.partial, kad gautumėte tą patį rezultatą)

Alternatyva yra sukurti atskirą kiekvieno mygtuko atgalinį ryšį, kuris gali sukelti kodų dubliavimą.

56
24 апр. Bryan Oakley atsakymas, pateiktas balandžio 24 d 2011-04-24 19:48 '11, 19:48, 2011-04-24 19:48

„Python“ lambda yra tik būdas apibrėžti inline funkcijas,

  a = lambda x: x + 1 распечатать a (1) Код> 

ir ..

  def a (x): return x + 1 распечатать a (1) Код> 

.. yra tikslūs .

Nėra nieko, ką galite padaryti su lambda, kad negalite daryti su įprastine funkcija - Python funkcijose yra objektas, kaip ir visa kita, ir lambdas tiesiog apibrėžia funkciją:

<Priemonė> <kodas → → a = lambda x: x + 1 →> įveskite) <type "function"> Code>

Aš nuoširdžiai tikiu, kad „ lambda raktinis žodis „Python“ yra nereikalingas - niekada nereikėjo jų naudoti (arba, jei naudosite įprastą funkciją, geriau suprasti, ar sąrašas ar daugelis įmontuotų funkcijų)

Dėl visiškai atsitiktinio pavyzdžio iš straipsnio „Python lambda yra sugedęs!“ :

Norėdami sužinoti, kaip lambda yra sugadinta, pabandykite sukurti funkcijų fs = [f0,..., f9] , kur fi (n) = я + n , pirmiausia pabandykite:

<Parminis> <kodas → → fs = [(lambda n: i + n) i intervale (10)] →> fs [3] (4) 13 Kodas>

Norėčiau teigti, kad net jei ji veiktų, būtų baisu ir „nereikšminga“, ta pati funkcija galėtų būti parašyta daugeliu kitų būdų, pavyzdžiui:

<Priedas> <kodas → → n = 4 →> [i + n i i intervale (10)] [4, 5, 6, 7, 8, 9, 10, 11, 12, 13] Kodas>

Taip, tai nėra tas pats dalykas, bet aš niekada neturėjau priežasties sukurti lambda funkcijų grupę sąraše. Tai gali būti prasminga kitomis kalbomis, tačiau „Python“ nėra „Haskell“ (arba „Lisp“, ar ...)

Atkreipkite dėmesį, kad mes galime naudoti lambda ir vis dar veda taip:

<Parminis> <kodas → → fs = [(lambda n, i = i: i + n) i intervale (10)] →> fs [3] (4) 7 Kodas>

Redaguoti:

Yra keletas atvejų, kai „lambda“ yra naudinga, pavyzdžiui, dažnai patogu jungti signalus PyQt programose, pavyzdžiui:

  w = PyQt4.QtGui.QLineEdit() w.textChanged.connect(событие lambda: dothing()) Код> 

Paprasčiausiai vykdant w.textChanged.connect(dothing) vadinamas dothing metodas su papildomu event argumentu ir dothing klaida. Naudodamiesi lambda įrankiais, mes galime atsargiai atsisakyti argumento neapibrėždami įvyniojimo funkcijos.

31
21 мая '09 в 5:03 2009-05-21 05:03 atsakė dbr gegužės 21, '09, 05:03 2009-05-21 05:03

Manau, kad lambda yra naudinga funkcijų, kurios daro tą patį, bet skirtingomis aplinkybėmis, sąrašui. Kaip ir „Mozilla“ daugiskaitos taisyklės .

 plural_rules = [ lambda n: 'all', lambda n: 'singular' if n == 1 else 'plural', lambda n: 'singular' if 0 <= n <= 1 else 'plural', ... ] # Call plural rule #1 with argument 4 to find out which sentence form to use. plural_rule[1](4) # returns 'plural' 

Jei jums reikia apibrėžti funkciją visiems tiems, kurie esate beprotiški iki galo. Taip pat būtų malonu su funkcijų pavadinimais, pvz., plural_rule_1 , plural_rule_2 ir kt. Ir jums reikės eval() kai esate funkcijų kintamojo identifikatoriaus plural_rule_2 .

28
16 янв. Atsakymas duotas Tor Valamo 16 jan. 2010-01-16 18:43 '10, 18:43, 2010-01-16 18:43

Beveik viską, ką galite padaryti su „ lambda , galite padaryti geriau su nurodytomis funkcijomis arba sąrašo ir generatoriaus išraiškomis.

Vadinasi, jūs paprastai turite būti viena iš jų bet kokioje situacijoje (galbūt išskyrus nulinį kodą, parašytą interaktyviame vertėjas).

26
20 мая '09 в 23:45 2009-05-20 23:45 atsakymą pateikė Aaron Maenpaa gegužės 20 d., 09:45 , 2009-05-20 23:45

Python naudoju jau keletą metų, ir aš niekada nesu susidūręs su situacija, kai man reikia lambda. Iš tiesų, kaip sako pamoka , tai tik sintaksiniam cukrui.

19
20 мая '09 в 23:47 2009-05-20 23:47 atsakymą pateikė Matt Schmidt gegužės 20 d., 23:47 2009-05-20 23:47

Aš negaliu kalbėti su pythonu apie specifinį lambda įgyvendinimą, bet apskritai lambda funkcijos yra tikrai patogu. Tai yra pagrindinis funkcinio programavimo metodas (galbūt net metodas), ir jie taip pat yra labai naudingi į objektą orientuotose programose. Tam tikrų tipų problemų atveju jie yra geriausias sprendimas, todėl, žinoma, neturėtumėte pamiršti!

Siūlau perskaityti glaudų ir žemėlapio funkciją (kuri nurodo „python“ dokumentus, tačiau ji egzistuoja beveik visomis kalbomis, kurios palaiko funkcines konstrukcijas), kad pamatytumėte, kodėl ji yra naudinga.

16
20 мая '09 в 23:45 2009-05-20 23:45 atsakymas pateikiamas rmeador gegužės 20 d., 09:45, 2009-05-20 23:45

Lambda funkcija yra ne biurokratiškas būdas sukurti funkciją.

Kas tai yra. Pvz., Darysime prielaidą, kad turite pagrindinę funkciją, ir jums reikia kvadratinių verčių. Pažvelkime į tradicinį būdą ir lambda kelią:

Tradicinis būdas:

 def main(): ... ... y = square(some_number) ... return something def square(x): return x**2 

Lambda:

 def main(): ... square = lambda x: x**2 y = square(some_number) return something 

Žiūrėkite skirtumą?

Lambda funkcijos labai gerai derinamos su sąrašais, pvz., Sąrašais ar žemėlapiais. Iš tiesų sąrašo supratimas yra „pythoninis“ būdas išreikšti save naudojant lambda. Pavyzdys:

 >>>a = [1,2,3,4] >>>[x**2 for x in a] [1,4,9,16] 

Pažiūrėkime, ką reiškia kiekvienas sintaksės elementas:

[]: „Duok man sąrašą“

x ** 2: „naudojant šį naujagimį“

x: a: "kiekviename a <elemente

Ar tai patogu? Tokių funkcijų sukūrimas. Leiskite jį perrašyti naudojant lambda:

 >>> square = lambda x: x**2 >>> [square(s) for x in a] [1,4,9,16] 

Dabar naudokime tą patį, bet kalbai neutralesnį žemėlapį. Kortelės priima 2 argumentus:

i) viena funkcija

(ii) pasikartojantis

Ir suteikia jums sąrašą, kuriame kiekvienas elementas, kurį jis taiko kiekvienam elementui, yra galimas.

Taigi, naudojant žemėlapį, turėtume:

 >>> a = [1,2,3,4] >>> squared_list = map(lambda x: x**2, a) 

Jei valdote lambdas ir žemėlapius, turėsite daug galių manipuliuoti duomenimis ir glaustai. Lambda funkcijos nėra nei paslėptos, nei kodo aiškumo. Negalima painioti kažko naujo su kažkuo nauja. Kai pradėsite juos naudoti, tai bus labai suprantama.

16
11 окт. Lucas Ribeiro atsakymas spalio 11 d 2013-10-11 06:03 '13, 6:03 am 2013-10-11 06:03

Vienas iš gražiausių dalykų apie lambda , kuris, mano nuomone, yra nepakankamas, yra tai, kad tai yra būdas atidėti paprastų formų vertinimą, kol bus reikalinga vertė. Leiskite man paaiškinti.

Daugelis bibliotekų procedūrų yra įgyvendinamos taip, kad kai kurie parametrai leistų būti nepagrįsti (iš kurių lambda yra viena). Idėja yra ta, kad tikroji vertė bus apskaičiuota tik tada, kai ji bus naudojama (greičiau, kai ji vadinama). Šis pavyzdys gali būti iliustruotas (pavyzdžiu). Tarkime, kad turite subroutiną, kuri turėjo užregistruoti tam tikrą laiką. Norite, kad paprogramė naudotų dabartinį laiką, atėmus 30 minučių. Jūs tai vadinate.

 log_timestamp(datetime.datetime.now() - datetime.timedelta(minutes = 30)) 

Dabar manau, kad tikroji funkcija bus iškviesta tik tada, kai įvyksta tam tikras įvykis, ir norite, kad laikmatis būtų skaičiuojamas tik tuo metu. Tai galite padaryti taip:

 log_timestamp(lambda : datetime.datetime.now() - datetime.timedelta(minutes = 30)) 

Darant prielaidą, kad log_timestamp gali apdoroti tokius skambučius, jis jį įvertins, kai jis bus reikalingas, ir tuo metu gausite laiko žymę.

Žinoma, yra alternatyvių būdų tai padaryti (pvz., Naudojant operator modulį), bet tikiuosi, kad šį klausimą pateiksiu.

Atnaujinimas: čia yra šiek tiek konkretesnis realaus pasaulio pavyzdys.

2 atnaujinimas: manau, kad tai yra pavyzdys, ką vadiname storu .

13
16 янв. Atsakymą pateikė Noufal Ibrahim 16 sausis 2010-01-16 18:30 '10, 18:30, 2010-01-16 18:30

Kaip jau minėta, „Python“ lambda operatorius apibrėžia anoniminę funkciją ir „Python“ funkcijas - uždarymą. Svarbu nesupainioti uždarymo sąvokos su lambda operatoriumi, kuris jiems yra tik sintaksinis metadonas.

Kai prieš kelerius metus pradėjau dirbti „Python“, aš daug naudojosi lambda, manydamas, kad jie buvo kieti ir sąrašai. Tačiau parašiau ir turėčiau išlaikyti didelę Python'e parašytą svetainę, kurioje yra keli tūkstančiai funkcinių taškų. Iš patirties žinojau, kad „lambdas“ gali būti gerai prototipams gaminti, bet nieko nedaryti dėl įmontuotų funkcijų (vadinamų uždarymais), išskyrus keletą raktų nutekėjimo ir kartais ne.

Iš esmės tai yra keli punktai:

  • lengviau skaityti programinę įrangą, kuri yra aiškiai parašyta prasmingais pavadinimais. Anoniminiai uždarymai pagal apibrėžimą negali turėti prasmingo pavadinimo, nes jie neturi pavadinimo. Matyt, šis trumpumas taip pat užkrečia lambda parametrus dėl kokios nors priežasties, todėl dažnai matome pavyzdžius, pvz., Lambda x: x + 1
  • lengviau pakartotinai naudoti užrašus, nes juos galima pavadinti daugiau nei vieną kartą, kai yra pavadinimas, kuriuo galima juos susieti.
  • tai yra lengviau ištaisyti kodą, kuris vietoj lambdas naudoja vadinamus uždarymus, nes pavadinimas bus rodomas tracebacks ir aplink klaidą.

Tai yra pakankama priežastis juos apvalinti ir paversti asmeniniais vardais. Tačiau aš turiu dar du nepasitenkinimą anoniminiais uždarymais.

Pirmasis nepasitenkinimas yra tik dar vienas nereikalingas raktinis žodis, kuris trukdo kalbai.

Antrasis nepasitenkinimas yra gilesnis ir paradigmos lygmeniu, t.y. Man nepatinka, kad jie skatina funkcinį programavimo stilių, nes šis stilius yra mažiau lankstus nei pranešimų perdavimo procesas, objektinis arba procedūrinis stilius, nes „lambda“ skaičiavimas nėra „Turing“ užbaigtas (laimei „Python“, mes vis tiek galime išeiti iš šio apribojimo net ir lambda viduje). Priežastys, kodėl manau, kad lambdas reklamuoja šį stilių:

  • Yra netiesioginė grąža, t.y. atrodo, kad jie turėtų būti funkcijos.

  • Jie suteikia alternatyvų mechanizmą, skirtą paslėpti valstybes kitam, aiškesniam, lengviau skaitomam, daugkartinio naudojimo ir bendresniam mechanizmui: metodams.

Aš stengiuosi parašyti „lambda“ neturintį „python“ ir išimkite lambda. Manau, Python bus šiek tiek geresnė kalba be lambda, bet tai tik mano nuomonė.

11
18 окт. Mike A atsakymas, pateiktas spalio 18 d. 2010-10-18 21:01 '10, 21:01, 2010-10-18 21:01

„Lambdas“ yra tikrai labai galingi konstruktai, atsirandantys iš idėjų funkciniame programavime, ir tai yra dalykas, kuris jokiu būdu nebus lengvai peržiūrimas, iš naujo apibrėžtas ar ištrintas netolimoje ateityje „Python“. Jie padeda jums parašyti galingesnį kodą, nes leidžia jums perduoti funkcijas kaip parametrus, taigi, kaip pirmos klasės piliečių funkcijų idėja.

Paprastai „Lambdas“ yra supainioti, bet kai jūs turite tvirtą supratimą, galite rašyti švarų, elegantišką kodą:

 squared = map(lambda x: x*x, [1, 2, 3, 4, 5]) 

Viršutinėje kodo eilutėje pateikiamas sąraše esančių numerių kvadratų sąrašas. Žinoma, galite tai padaryti taip pat:

 def square(x): return x*x squared = map(square, [1, 2, 3, 4, 5]) 

Akivaizdu, kad senas kodas yra trumpesnis, ir tai ypač aktualu, jei ketinate naudoti žemėlapio funkciją (arba panašią funkciją, kuri atlieka funkciją kaip parametrą) tik vienoje vietoje. Jis taip pat suteikia kodui intuityvesnį ir elegantiškesnį.

Be to, kaip savo atsakyme pažymėjo @Davidas Zaslavskis, supratimo sąrašai ne visada turi būdą, ypač jei jūsų sąrašas turėtų gauti vertes iš tam tikro neaiškaus matematinio kelio.

Praktiniu požiūriu vienas iš didžiausių „lambdas“ privalumų man neseniai buvo grafinėje sąsajoje ir renginiuose. Jei žiūrite į „Tkinter“ grįžtamąjį ryšį, viskas, ką jie priima kaip argumentus, yra įvykis, kuris juos sukėlė. Pavyzdžiui.

 def define_bindings(widget): widget.bind("<Button-1>", do-something-cool) def do-something-cool(event): #Your code to execute on the event trigger 

Dabar, jei turite kokių nors argumentų? Kažkas taip paprasta, kaip du argumentai, skirti saugoti pelės paspaudimų koordinates. Tai galite padaryti taip:

 def main(): # define widgets and other imp stuff x, y = None, None widget.bind("<Button-1>", lambda event: do-something-cool(x, y)) def do-something-cool(event, x, y): x = event.x y = event.y #Do other cool stuff 

Dabar galite teigti, kad tai gali būti padaryta naudojant pasaulinius kintamuosius, bet ar tikrai norite, kad jūsų galva nerimautų dėl atminties valdymo ir nutekėjimo, ypač jei pasaulinis kintamasis bus naudojamas tik vienoje konkrečioje vietoje? Tai bus tik blogas programavimo stilius.

Trumpai tariant, lambdas yra nuostabus ir niekada neturėtų būti nepakankamai įvertintas. Python lambdas yra ne tas pats, kaip LISP lambdas (galingesni), bet su jais tikrai galite padaryti daug magiškų dalykų.

11
24 мая '13 в 16:02 2013-05-24 16:02 atsakymas pateikiamas varagrawal gegužės 24 d. 13 val. 16:02 2013-05-24 16:02

Lambdas yra glaudžiai susijęs su funkciniu programavimo stiliu. Idėja, kad jūs galite išspręsti problemas pritaikydami tam tikrus duomenis ir derindamos rezultatus, yra tai, ką „Google“ naudoja daugumai algoritmų.

Funkcinio programavimo būdu parašytos programos yra lengvai lyginamos ir todėl tampa vis svarbesnės su šiuolaikinėmis daugiašalėmis mašinomis. Trumpai tariant, NE, jūs neturite pamiršti jų.

8
20 мая '09 в 23:46 2009-05-20 23:46 atsakymas duotas „ Yogi“ gegužės 20 d., 09:46, 2009-05-20 23:46

Pirmasis pasveikinimas, kuris sugebėjo išsiaiškinti lambda. Mano nuomone, tai yra tikrai galingas darbas. Šių dienų tendencija į funkcines programavimo kalbas tikrai rodo, kad to nereikėtų vengti, ir artimiausioje ateityje ji nebus iš naujo apibrėžta.

Jums reikia šiek tiek kitaip galvoti. Esu tikras, kad jums tai patiks netrukus. Bet būkite atsargūs, jei elgiatės tik su python. Kadangi lambda nėra tikras uždarymas, jis kažkaip yra „skaldytas“: „ Pambonai “ neveikia

6
20 мая '09 в 23:47 2009-05-20 23:47 Atsakymą davė Norbert Hartl gegužės 09 d. 23:47 2009-05-20 23:47

Galiu jums pateikti pavyzdį, kur man tikrai reikia lambda. Sukuriu grafinę programą, kurioje dešiniuoju pelės klavišu spustelėkite failą ir priskiriama viena iš trijų parinkčių. Pasirodo, kad Tkinter (GUI sąsaja, kurioje rašau tai), kai kas nors paspaudžia mygtuką, jis negali būti priskirtas komandai, kuri priima argumentus. Поэтому, если бы я выбрал один из вариантов и хотел, чтобы результат моего выбора был таким:

 print 'hi there'