Mana yang lebih disukai untuk digunakan: fungsi lambda atau fungsi bersarang ('def')?

102

Saya kebanyakan menggunakan fungsi lambda tetapi terkadang menggunakan fungsi bersarang yang tampaknya memberikan perilaku yang sama.

Berikut adalah beberapa contoh sepele di mana mereka secara fungsional melakukan hal yang sama jika keduanya ditemukan dalam fungsi lain:

Fungsi Lambda

>>> a = lambda x : 1 + x
>>> a(5)
6

Fungsi bersarang

>>> def b(x): return 1 + x

>>> b(5)
6

Apakah ada keuntungan menggunakan salah satu dari yang lain? (Kinerja? Keterbacaan? Keterbatasan? Konsistensi? Dll.)

Apakah itu penting? Jika tidak maka apakah itu melanggar prinsip Pythonic:

Seharusnya ada satu — dan sebaiknya hanya satu — cara yang jelas untuk melakukannya .

sinar
sumber

Jawaban:

106

Jika Anda perlu menetapkannya lambdake sebuah nama, gunakan a def. defs hanyalah gula sintaksis untuk sebuah tugas, jadi hasilnya sama, dan jauh lebih fleksibel dan mudah dibaca.

lambdas dapat digunakan untuk digunakan sekali, buang fungsi yang tidak memiliki nama.

Namun, kasus penggunaan ini sangat jarang. Anda jarang perlu meneruskan objek fungsi yang tidak disebutkan namanya.

Bawaan map()dan filter()objek fungsi kebutuhan, tetapi daftar pemahaman dan ekspresi generator umumnya lebih mudah dibaca daripada fungsi tersebut dan dapat mencakup semua kasus penggunaan, tanpa memerlukan lambda.

Untuk kasus Anda benar-benar membutuhkan objek fungsi kecil, Anda harus menggunakan operatorfungsi modul, seperti operator.adddaripadalambda x, y: x + y

Jika Anda masih membutuhkan beberapa lambdatidak tercakup, Anda mungkin mempertimbangkan untuk menulis a def, agar lebih mudah dibaca. Jika fungsinya lebih kompleks daripada yang ada di operatormodul, a defmungkin lebih baik.

Jadi, lambdakasus penggunaan yang baik di dunia nyata sangat jarang.

nosklo.dll
sumber
9
Saya setuju dengan jawaban kapan harus digunakan lambda, tapi saya tidak setuju bahwa ini "sangat jarang", ini umum untuk fungsi tombol sortedatau itertools.groupbydll., Misalnyasorted(['a1', 'b0'], key= lambda x: int(x[1]))
Chris_Rands
30

Secara praktis, bagi saya ada dua perbedaan:

Yang pertama adalah tentang apa yang mereka lakukan dan apa yang mereka hasilkan:

  • def adalah kata kunci yang tidak mengembalikan apa pun dan membuat 'nama' di namespace lokal.

  • lambda adalah kata kunci yang mengembalikan objek fungsi dan tidak membuat 'nama' di namespace lokal.

Karenanya, jika Anda perlu memanggil fungsi yang mengambil objek fungsi, satu-satunya cara untuk melakukannya dalam satu baris kode python adalah dengan lambda. Tidak ada padanan dengan def.

Dalam beberapa kerangka kerja ini sebenarnya cukup umum; misalnya, saya sering menggunakan Twisted , dan melakukan sesuatu seperti

d.addCallback(lambda result: setattr(self, _someVariable, result))

cukup umum, dan lebih ringkas dengan lambda.

Perbedaan kedua adalah tentang fungsi sebenarnya yang boleh dilakukan.

  • Fungsi yang didefinisikan dengan 'def' dapat berisi kode python apa pun
  • Fungsi yang didefinisikan dengan 'lambda' harus mengevaluasi ke ekspresi, dan karenanya tidak dapat berisi pernyataan seperti print, import, raise, ...

Sebagai contoh,

def p(x): print x

bekerja seperti yang diharapkan, sementara

lambda x: print x

adalah SyntaxError.

Tentu saja, ada beberapa solusi - ganti printdengan sys.stdout.write, atau importdengan __import__. Tetapi biasanya Anda lebih baik menggunakan fungsi dalam kasus itu.

Thomas Vander Stichele
sumber
23

Dalam wawancara ini, Guido van Rossum mengatakan dia berharap dia tidak membiarkan 'lambda' menjadi Python:

" Q. Fitur apa dari Python yang paling tidak Anda sukai?

Terkadang saya terlalu cepat menerima kontribusi, dan kemudian menyadari bahwa itu adalah kesalahan. Salah satu contohnya adalah beberapa fitur pemrograman fungsional, seperti fungsi lambda. Lambda adalah kata kunci yang memungkinkan Anda membuat fungsi anonim kecil; fungsi bawaan seperti memetakan, memfilter, dan mengurangi menjalankan fungsi melalui jenis urutan, seperti daftar.

Dalam praktiknya, hasilnya tidak sebaik itu. Python hanya memiliki dua cakupan: lokal dan global. Hal ini membuat penulisan fungsi lambda menjadi menyakitkan, karena Anda sering ingin mengakses variabel dalam lingkup tempat lambda didefinisikan, tetapi Anda tidak bisa karena kedua cakupan tersebut. Ada jalan lain untuk menyiasatinya, tapi ini semacam kludge. Seringkali tampaknya jauh lebih mudah dengan Python untuk hanya menggunakan perulangan for daripada mengotak-atik fungsi lambda. map dan teman bekerja dengan baik hanya jika sudah ada fungsi bawaan yang melakukan apa yang Anda inginkan.

IMHO, Iambdas kadang-kadang bisa nyaman, tetapi biasanya nyaman dengan mengorbankan kesiapan. Bisakah Anda memberi tahu saya apa fungsinya:

str(reduce(lambda x,y:x+y,map(lambda x:x**x,range(1,1001))))[-10:]

Saya menulisnya, dan butuh waktu satu menit untuk mengetahuinya. Ini dari Project Euler - saya tidak akan mengatakan masalah mana karena saya benci spoiler, tetapi berjalan dalam 0,124 detik :)

Chris Lawlor
sumber
20
Perhatikan bahwa wawancara tersebut agak lama, dan Python telah lama menambahkan cakupan bersarang, yang membuat argumen yang dia berikan terhadap lambda tidak lagi relevan. Saya yakin dia masih menyesali lambda, tetapi tidak cukup untuk menghapusnya dengan Python 3.0.
Thomas Wouters
10
Sungguh contoh Anda harus menjadi argumen yang menentang satu kalimat, bukan lambda. Selain itu, Anda harus menggunakan fungsi penjumlahan bawaan daripada mengurangi dengan lambda: str (sum (map (lambda x: x ** x, range (1001)))) [: - 10]
Triptych
2
@ThomasWouters: Saya mengerti bahwa lambdatidak dihapus di 3.0 adalah hal yang dekat, dan bahwa Guido tidak berjuang untuk mempertahankannya.
Ethan Furman
11

Untuk n = 1000 inilah beberapa waktu untuk memanggil fungsi vs lambda:

In [11]: def f(a, b):
             return a * b

In [12]: g = lambda x, y: x * y

In [13]: %%timeit -n 100
for a in xrange(n):
  for b in xrange(n):
    f(a, b)
   ....:
100 loops, best of 3: 285 ms per loop

In [14]: %%timeit -n 100
for a in xrange(n):
  for b in xrange(n):
    g(a, b)
   ....:
100 loops, best of 3: 298 ms per loop

In [15]: %%timeit -n 100
for a in xrange(n):
  for b in xrange(n):
    (lambda x, y: x * y)(a, b)
   ....:
100 loops, best of 3: 462 ms per loop
Andy Hayden
sumber
3
Menarik untuk melihat bahwa lambda dan versi yang ditentukan kira-kira setara. Tes terakhir membutuhkan lebih banyak waktu karena python mungkin perlu mengalokasikan ruang setiap kali mendefinisikan fungsi lambda itu.
hlin117
Saya kira ini masuk akal karena definisinya dapat merujuk pada variabel lokal (yang mungkin telah berubah) ... meskipun dalam kasus di mana tidak, seperti di sini, cpython dapat melakukan pekerjaan yang lebih baik.
Andy Hayden
Gunakan dis.dis; (Lambda x, y: x * y) Anda membuat fungsi setiap loop. Jika Anda membuat lambda sebelum loop (alias f = lambda x, y: x * y), bytecode untuk memanggil fungsi tersebut akan sama persis dengan g / f dalam contoh sebelumnya, oleh karena itu performa lambda akan sama sebagai fungsi def. Jadi lambda atau def sebagai tidak berdampak jika Anda menggunakannya sama. Lakukan kebalikannya, nyatakan fungsi f () dalam loop, lalu panggil ...
tito
@ Tito Saya yakin itulah yang ditunjukkan oleh 3 contoh waktu ...
Andy Hayden
@ Tito oh, Anda mengatakan mendefinisikan fungsi dalam loop, tentu, tapi saya berpendapat itu pola yang tidak biasa. Tidak yakin mengapa ini membutuhkan suara negatif pada komentar itu ...
Andy Hayden
7

Performa:

Membuat fungsi dengan lambdaini sedikit lebih cepat daripada menciptakan dengan def. Perbedaannya adalah karena defmembuat entri nama di tabel penduduk setempat. Fungsi yang dihasilkan memiliki kecepatan eksekusi yang sama.


Keterbacaan:

Fungsi Lambda agak kurang dapat dibaca oleh sebagian besar pengguna Python, tetapi juga jauh lebih ringkas dalam beberapa keadaan. Pertimbangkan untuk mengubah dari menggunakan rutinitas non-fungsional ke fungsional:

# Using non-functional version.

heading(math.sqrt(v.x * v.x + v.y * v.y), math.atan(v.y / v.x))

# Using lambda with functional version.

fheading(v, lambda v: math.sqrt(v.x * v.x + v.y * v.y), lambda v: math.atan(v.y / v.x))

# Using def with functional version.

def size(v):
    return math.sqrt(v.x * v.x + v.y * v.y)

def direction(v):
    return math.atan(v.y / v.x)

deal_with_headings(v, size, direction)

Seperti yang Anda lihat, lambdaversi ini lebih pendek dan "lebih mudah" dalam arti bahwa Anda hanya perlu menambahkan lambda v:ke versi non-fungsional asli untuk mengubahnya ke versi fungsional. Ini juga jauh lebih ringkas. Tapi ingat, banyak pengguna Python akan bingung dengan sintaks lambda, jadi apa yang Anda kehilangan panjangnya dan kompleksitas sebenarnya mungkin diperoleh kembali dalam kebingungan dari sesama pembuat kode.


Batasan:

  • lambda fungsi hanya dapat digunakan sekali, kecuali ditetapkan ke nama variabel.
  • lambdafungsi yang ditetapkan ke nama variabel tidak memiliki keunggulan dibandingkan deffungsi.
  • lambda fungsi bisa sulit atau tidak mungkin untuk dibuat acar.
  • def nama fungsi harus dipilih dengan cermat agar cukup deskriptif dan unik atau setidaknya tidak digunakan dalam cakupan.

Konsistensi:

Python kebanyakan menghindari konvensi pemrograman fungsional demi semantik prosedural dan objektif yang lebih sederhana. The lambdaOperator berdiri di kontras dengan bias ini. Selain itu, sebagai alternatif dari yang sudah lazim def, lambdafungsi menambahkan keragaman pada sintaks Anda. Beberapa akan menganggap itu kurang konsisten.


Fungsi yang sudah ada sebelumnya:

Seperti dicatat oleh orang lain, banyak kegunaan lambdadi lapangan dapat diganti oleh anggota operatoratau modul lain. Misalnya:

do_something(x, y, lambda x, y: x + y)
do_something(x, y, operator.add)

Menggunakan fungsi yang sudah ada sebelumnya dapat membuat kode lebih mudah dibaca dalam banyak kasus.


Prinsip Pythonic: “Harus ada satu — dan sebaiknya hanya satu — cara yang jelas untuk melakukannya”

Itu serupa dengan doktrin sumber tunggal kebenaran . Sayangnya, prinsip satu-cara-untuk-melakukannya selalu lebih merupakan aspirasi yang menyedihkan untuk Python, daripada prinsip pembimbing yang sebenarnya. Pertimbangkan pemahaman array yang sangat kuat dengan Python. Mereka secara fungsional setara dengan fungsi mapdan filter:

[e for e in some_array if some_condition(e)]
filter(some_array, some_condition)

lambdadan defsama.

Ini masalah opini, tapi saya akan mengatakan bahwa apapun dalam bahasa Python yang ditujukan untuk penggunaan umum yang jelas tidak merusak apapun sudah cukup "Pythonic".

Pi Marillion
sumber
7

Lebih disukai: fungsi lambda atau fungsi bersarang ( def)?

Ada satu keuntungan menggunakan lambda dibandingkan fungsi reguler: fungsi tersebut dibuat dalam ekspresi.

Ada beberapa kekurangan:

  • tidak ada nama (hanya '<lambda>')
  • tidak ada dokumen
  • tidak ada penjelasan
  • tidak ada pernyataan yang rumit

Keduanya juga merupakan jenis objek yang sama. Untuk alasan tersebut, saya biasanya lebih suka membuat fungsi dengan defkata kunci daripada dengan lambda.

Poin pertama - mereka adalah tipe objek yang sama

Sebuah lambda menghasilkan tipe objek yang sama dengan fungsi biasa

>>> l = lambda: 0
>>> type(l)
<class 'function'>
>>> def foo(): return 0
... 
>>> type(foo)
<class 'function'>
>>> type(foo) is type(l)
True

Karena lambda adalah fungsi, mereka adalah objek kelas satu.

Baik lambda dan fungsi:

  • dapat diedarkan sebagai argumen (sama seperti fungsi biasa)
  • ketika dibuat dalam fungsi luar menjadi penutupan atas lokal fungsi luar itu

Tetapi lambda, secara default, kehilangan beberapa hal yang didapat fungsi melalui sintaks definisi fungsi penuh.

Lamba __name__adalah'<lambda>'

Lambda adalah fungsi anonim, jadi mereka tidak tahu namanya sendiri.

>>> l.__name__
'<lambda>'
>>> foo.__name__
'foo'

Jadi lambda's tidak dapat dicari secara terprogram di namespace mereka.

Ini membatasi hal-hal tertentu. Misalnya, foodapat dicari dengan kode serial, sementara ltidak bisa:

>>> import pickle
>>> pickle.loads(pickle.dumps(l))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
_pickle.PicklingError: Can't pickle <function <lambda> at 0x7fbbc0464e18>: 
attribute lookup <lambda> on __main__ failed

Kita dapat mencari dengan foobaik - karena mengetahui namanya sendiri:

>>> pickle.loads(pickle.dumps(foo))
<function foo at 0x7fbbbee79268>

Lambdas tidak memiliki anotasi dan tidak ada docstring

Pada dasarnya, lambda tidak didokumentasikan. Mari menulis ulang fooagar terdokumentasi lebih baik:

def foo() -> int:
    """a nullary function, returns 0 every time"""
    return 0

Sekarang, foo memiliki dokumentasi:

>>> foo.__annotations__
{'return': <class 'int'>}
>>> help(foo)
Help on function foo in module __main__:

foo() -> int
    a nullary function, returns 0 every time

Padahal, kami tidak memiliki mekanisme yang sama untuk memberikan informasi yang sama ke lambda:

>>> help(l)
Help on function <lambda> in module __main__:

<lambda> lambda (...)

Tapi kita bisa meretasnya:

>>> l.__doc__ = 'nullary -> 0'
>>> l.__annotations__ = {'return': int}
>>> help(l)
Help on function <lambda> in module __main__:

<lambda> lambda ) -> in
    nullary -> 0

Tapi mungkin ada beberapa kesalahan yang mengacaukan hasil bantuan.

Lambdas hanya bisa mengembalikan ekspresi

Lambdas tidak bisa mengembalikan pernyataan kompleks, hanya ekspresi.

>>> lambda: if True: 0
  File "<stdin>", line 1
    lambda: if True: 0
             ^
SyntaxError: invalid syntax

Ekspresi memang bisa jadi agak rumit, dan jika Anda berusaha sangat keras, Anda mungkin dapat mencapai hal yang sama dengan lambda, tetapi kerumitan yang ditambahkan lebih merugikan penulisan kode yang jelas.

Kami menggunakan Python untuk kejelasan dan pemeliharaan. Penggunaan lambda yang berlebihan bisa melawan itu.

Satu- satunya keuntungan lambda: bisa dibuat dalam satu ekspresi

Ini adalah satu-satunya kemungkinan kenaikan. Karena Anda dapat membuat lambda dengan ekspresi, Anda dapat membuatnya di dalam pemanggilan fungsi.

Membuat fungsi di dalam panggilan fungsi menghindari pencarian nama (murah) versus yang dibuat di tempat lain.

Namun, karena Python dievaluasi secara ketat, tidak ada perolehan performa lain selain menghindari pencarian nama.

Untuk ekspresi yang sangat sederhana, saya mungkin memilih lambda.

Saya juga cenderung menggunakan lambda saat melakukan Python interaktif, untuk menghindari banyak baris saat seseorang melakukannya. Saya menggunakan jenis format kode berikut ketika saya ingin meneruskan argumen ke konstruktor saat memanggil timeit.repeat:

import timeit

def return_nullary_lambda(return_value=0):
    return lambda: return_value

def return_nullary_function(return_value=0):
    def nullary_fn():
        return return_value
    return nullary_fn

Dan sekarang:

>>> min(timeit.repeat(lambda: return_nullary_lambda(1)))
0.24312214995734394
>>> min(timeit.repeat(lambda: return_nullary_function(1)))
0.24894469301216304

Saya percaya sedikit perbedaan waktu di atas dapat dikaitkan dengan pencarian nama di return_nullary_function- perhatikan bahwa itu sangat dapat diabaikan.

Kesimpulan

Lambda bagus untuk situasi informal di mana Anda ingin meminimalkan baris kode untuk membuat titik tunggal.

Lambda buruk untuk situasi yang lebih formal di mana Anda memerlukan kejelasan untuk editor kode yang akan datang nanti, terutama dalam kasus di mana mereka tidak sepele.

Kami tahu kami harus memberikan nama yang baik pada objek kami. Bagaimana kita bisa melakukannya jika objek tidak memiliki nama?

Untuk semua alasan ini, saya biasanya lebih suka membuat fungsi dengan defdaripada dengan lambda.

Aaron Hall
sumber
6

Saya setuju dengan saran nosklo: jika Anda perlu memberi nama fungsi, gunakan def. Saya memesan lambdafungsi untuk kasus di mana saya hanya meneruskan cuplikan singkat kode ke fungsi lain, misalnya:

a = [ (1,2), (3,4), (5,6) ]
b = map( lambda x: x[0]+x[1], a )
Dan Lenski
sumber
3
Di sebagian besar kombinasi map / lambda, Anda dapat menggantinya dengan pemahaman daftar atau fungsi yang lebih sesuai. Misalnya, "map (sum, a)" atau "[x [0] + x [1] for x in a]"
John Millikin
Ya itu benar. Terkadang saya lebih suka map (). Ini sebagian besar hanyalah contoh buatan menggunakan fungsi in-line.
Dan Lenski
persis ... Kebanyakan contoh dibuat-buat, karena tidak wajar untuk digunakan dan ada cara praktis yang lebih baik dalam banyak kasus.
nosklo
5

Meskipun setuju dengan jawaban lain, terkadang lebih mudah dibaca. Berikut ini adalah contoh di mana lambdasangat berguna, dalam kasus penggunaan saya terus menghadapi suatu N dimensi defaultdict.
Berikut contohnya:

from collections import defaultdict
d = defaultdict(lambda: defaultdict(list))
d['Foo']['Bar'].append(something)

Saya merasa lebih mudah dibaca daripada membuat defuntuk dimensi kedua. Ini bahkan lebih signifikan untuk dimensi yang lebih tinggi.

Jonathan
sumber
from functools import partial; defaultdict(partial(defaultdict, list)). Tetapkan parsial ke sebuah nama jika Anda ingin menggunakannya lebih dari sekali. Tetapi, jika Anda terus menemukan konstruksi ini, itu berarti Anda tidak KERING. Faktorkan menjadi pustaka utilitas. Anda dapat menggunakan konstruksi ini untuk membuat defaultdict n-dimensi arbiter menggunakan functools lain (atau loop atau rekursi).
DylanYoung
3

Penggunaan utama lambda selalu untuk fungsi callback sederhana, dan untuk map, reduce, filter, yang memerlukan fungsi sebagai argumen. Dengan pemahaman daftar menjadi norma, dan tambahan diperbolehkan jika seperti:

x = [f for f in range(1, 40) if f % 2]

Sulit membayangkan kasus nyata penggunaan lambda dalam penggunaan sehari-hari. Akibatnya, menurut saya, hindari lambda dan buat fungsi bersarang.

apg
sumber
3

Batasan penting lambda adalah bahwa lambda tidak dapat berisi apa pun selain ekspresi. Hampir tidak mungkin bagi ekspresi lambda untuk menghasilkan apa pun selain efek samping yang sepele, karena tidak dapat memiliki tubuh yang sekaya deffungsi 'ed.

Karena itu, Lua memengaruhi gaya pemrograman saya terhadap penggunaan fungsi anonim secara ekstensif, dan saya mengotori kode saya dengan mereka. Selain itu, saya cenderung berpikir tentang map / reduce sebagai operator abstrak dengan cara yang tidak saya anggap sebagai pemahaman daftar atau generator, hampir seperti jika saya menunda keputusan implementasi secara eksplisit dengan menggunakan operator tersebut.

Sunting: Ini adalah pertanyaan yang cukup lama, dan pendapat saya tentang masalah ini agak berubah.

Pertama, saya sangat bias terhadap penempatan lambdaekspresi ke variabel; karena python memiliki sintaks khusus hanya untuk itu (petunjuk, def). Selain itu, banyak penggunaan lambda, meskipun tidak mendapatkan nama, memiliki implementasi yang ditentukan sebelumnya (dan lebih efisien). Misalnya, contoh yang dimaksud dapat disingkat menjadi hanya (1).__add__, tanpa perlu membungkusnya dengan lambdaatau def. Banyak kegunaan umum lainnya yang dapat dipenuhi dengan beberapa kombinasi dari operator, itertoolsdan functoolsmodul.

SingleNegationElimination
sumber
1
(1).__add__- memanggil metode dunder secara langsung seharusnya hampir tidak pernah terjadi. Seribu lambdadetik untuk setiap panggilan darurat langsung.
Ethan Furman
1
@EthanFurman: Nah, menurut pengalaman saya, panggilan alam (1).__add__agak tidak umum, tetapi saya tidak akan mendekati "seharusnya". tanpa ragu, saya menemukan yang pertama jauh lebih mudah dibaca lambda x: 1 + x. Jika kita memiliki sesuatu yang lebih mirip dengan notasi irisan haskell, (1+)itu akan bagus, tapi kita harus puas dengan apa yang secara semantik persisnya, nama metode dunder.
SingleNegationElimination
2
  • Waktu komputasi.
  • Fungsi tanpa nama.
  • Untuk mencapai Satu fungsi dan banyak fungsi penggunaan.

Mempertimbangkan contoh sederhana,

# CREATE ONE FUNCTION AND USE IT TO PERFORM MANY OPERATIONS ON SAME TYPE OF DATA STRUCTURE.
def variousUse(a,b=lambda x:x[0]):
    return [b(i) for i in a]

dummyList = [(0,1,2,3),(4,5,6,7),(78,45,23,43)]
variousUse(dummyList)                           # extract first element
variousUse(dummyList,lambda x:[x[0],x[2],x[3]]) # extract specific indexed element
variousUse(dummyList,lambda x:x[0]+x[2])        # add specific elements
variousUse(dummyList,lambda x:x[0]*x[2])        # multiply specific elements
patel bhargav
sumber
1

Jika Anda hanya akan menetapkan lambda ke variabel dalam lingkup lokal, Anda juga dapat menggunakan def karena lebih mudah dibaca dan dapat diperluas dengan lebih mudah di masa mendatang:

fun = lambda a, b: a ** b # a pointless use of lambda
map(fun, someList)

atau

def fun(a, b): return a ** b # more readable
map(fun, someList)
terlalu banyak php
sumber
Keduanya from operator import pow;map(pow, someList)dan (a**b for a,b in someList)bahkan lebih mudah dibaca.
InQβ
1

Satu kegunaan lambda yang saya temukan ... ada dalam pesan debug.

Karena lambda dapat dievaluasi dengan malas, Anda dapat memiliki kode seperti ini:

log.debug(lambda: "this is my message: %r" % (some_data,))

daripada mungkin mahal:

log.debug("this is my message: %r" % (some_data,))

yang memproses string format meskipun panggilan debug tidak menghasilkan keluaran karena tingkat logging saat ini.

Tentu saja agar dapat bekerja seperti yang dijelaskan modul logging yang digunakan harus mendukung lambda sebagai "parameter malas" (seperti modul logging saya).

Ide yang sama dapat diterapkan pada kasus evaluasi malas lainnya untuk pembuatan nilai konten sesuai permintaan.

Misalnya operator terner adat ini:

def mif(condition, when_true, when_false):
    if condition:
         return when_true()
    else:
         return when_false()

mif(a < b, lambda: a + a, lambda: b + b)

dari pada:

def mif(condition, when_true, when_false):
    if condition:
         return when_true
    else:
         return when_false

mif(a < b, a + a, b + b)

dengan lambda hanya ekspresi yang dipilih oleh kondisi yang akan dievaluasi, tanpa lambda keduanya akan dievaluasi.

Tentu saja Anda bisa menggunakan fungsi sebagai ganti lambda, tetapi untuk ekspresi pendek lambda adalah (c) lebih ramping.

Glushiator
sumber
1
NB loggingsudah memiliki format lazy: log.debug("this is my message: %r", some_data)hanya akan diformat jika / jika pesan diminta.
j08lue
@ j08lue metode lambda melewatkan evaluasi segala sesuatu jika keluaran debug tidak dihasilkan, dalam kasus yang Anda tunjukkan some_datadapat berupa ekspresi atau pemanggilan fungsi / metode yang mahal.
Glushiator
0

Saya setuju dengan nosklo. Ngomong-ngomong, bahkan dengan sekali pakai, buang fungsi, sebagian besar waktu Anda hanya ingin menggunakan sesuatu dari modul operator.

TELUR:

Anda memiliki fungsi dengan tanda tangan ini: myFunction (data, fungsi panggilan balik).

Anda ingin melewatkan fungsi yang menambahkan 2 elemen.

Menggunakan lambda:

myFunction(data, (lambda x, y : x + y))

Cara pythonic:

import operator
myFunction(data, operator.add)

Atau tentu saja ini adalah contoh sederhana, tetapi ada banyak hal yang disediakan oleh modul operator, termasuk item setter / getter untuk list dan dict. Benar-benar keren.

e-satis
sumber
-1

Perbedaan utama adalah Anda tidak dapat menggunakan deffungsi sebaris, yang menurut saya kasus penggunaan yang paling nyaman untuk suatu lambdafungsi. Misalnya saat mengurutkan daftar objek:

my_list.sort(key=lambda o: o.x)

Oleh karena itu, saya menyarankan agar penggunaan lambda untuk operasi sepele semacam ini, yang juga tidak benar-benar mendapatkan keuntungan dari dokumentasi otomatis yang disediakan dengan menamai fungsi tersebut.

Ali Rasim Kocal
sumber
-2

lambda berguna untuk menghasilkan fungsi baru:

>>> def somefunc(x): return lambda y: x+y
>>> f = somefunc(10)
>>> f(2)
12
>>> f(4)
14
scrpy
sumber