Saya pernah mendengar bahwa multiline lambdas tidak dapat ditambahkan dengan Python karena mereka akan berbenturan secara sintaksis dengan konstruksi sintaks lainnya dalam Python. Saya sedang memikirkan hal ini di bus hari ini dan menyadari bahwa saya tidak dapat memikirkan konstruksi Python tunggal yang bertentangan dengan lambdas multiline. Karena saya tahu bahasanya dengan baik, ini mengejutkan saya.
Sekarang, saya yakin Guido punya alasan untuk tidak memasukkan lambda multiline ke dalam bahasa itu, tetapi karena penasaran: bagaimana situasi di mana termasuk lambda multiline akan ambigu? Apakah yang saya dengar benar, atau adakah alasan lain mengapa Python tidak mengizinkan lambda multiline?
lambda
ekspresi terlebih dahulu; Anda cukup menggunakandef
pernyataan dalam ekspresi.Jawaban:
Lihatlah yang berikut ini:
Apakah ini lambda yang kembali
(y, [1,2,3])
(sehingga peta hanya mendapatkan satu parameter, menghasilkan kesalahan)? Atau apakah itu kembaliy
? Atau apakah itu kesalahan sintaksis, karena koma pada baris baru salah tempat? Bagaimana Python tahu apa yang Anda inginkan?Di dalam parens, lekukan tidak menjadi masalah bagi python, jadi Anda tidak dapat bekerja dengan multinines.
Ini hanya yang sederhana, mungkin ada lebih banyak contoh.
sumber
Guido van Rossum (penemu Python) menjawab pertanyaan persis ini sendiri di sebuah posting blog lama .
Pada dasarnya, ia mengakui bahwa secara teori itu mungkin, tetapi bahwa solusi apa pun yang diajukan akan tidak Pythonic:
sumber
Ini umumnya sangat jelek (tapi terkadang alternatifnya bahkan lebih jelek), jadi solusinya adalah dengan membuat ekspresi kawat gigi:
Itu tidak akan menerima tugas apa pun, jadi Anda harus menyiapkan data terlebih dahulu. Tempat saya menemukan ini berguna adalah pembungkus PySide, di mana Anda kadang-kadang memiliki panggilan balik singkat. Menulis fungsi anggota tambahan akan lebih jelek. Biasanya Anda tidak membutuhkan ini.
Contoh:
sumber
lambda arg
dansetattr(arg, 'attr','value')
menumbangkan "tidak ada tugas ...". Dan kemudian ada evaluasi hubung singkatand
danor
... Javascript yang melakukannya. Tenggelamkan akar ke dalam dirimu, seperti ivy ke dinding. Saya hampir berharap saya melupakan ini selama Natal.PEP
pedoman)Beberapa tautan yang relevan:
Untuk sementara, saya mengikuti pengembangan Reia, yang awalnya akan memiliki sintaksis Python berdasarkan lekukan dengan blok Ruby juga, semua di atas Erlang. Tapi, sang desainer akhirnya menyerah pada sensitivitas lekukan, dan posting ini ia menulis tentang keputusan itu termasuk diskusi tentang masalah yang ia hadapi dengan lekukan + blok multi-line, dan peningkatan apresiasi yang ia dapatkan untuk masalah / keputusan desain Guido:
http://www.unlimitednovelty.com/2009/03/indentation-sensitivity-post-mortem.html
Juga, berikut ini adalah proposal yang menarik untuk blok gaya-Ruby di Python yang saya jalankan di mana Guido memposting respons tanpa benar-benar menembaknya (meskipun tidak yakin apakah telah terjadi penurunan berikutnya):
http://tav.espians.com/ruby-style-blocks-in-python.html
sumber
[Sunting] Baca jawaban ini.Ini menjelaskan mengapa multiline lambda bukanlah suatu hal.
Sederhananya, itu unpythonic. Dari posting blog Guido van Rossum:
sumber
Izinkan saya mempersembahkan kepada Anda hack yang mulia tetapi menakutkan:
Anda sekarang dapat menggunakan
LET
formulir ini sebagai berikut:pemberian yang mana:
[0, 3, 8]
sumber
Saya bersalah mempraktikkan peretasan kotor ini di beberapa proyek saya yang sedikit lebih sederhana:
Saya harap Anda dapat menemukan cara untuk tetap pythonic tetapi jika Anda harus melakukannya ini tidak begitu menyakitkan daripada menggunakan exec dan memanipulasi global.
sumber
Biarkan saya mencoba untuk mengatasi masalah parsing @balpha. Saya akan menggunakan tanda kurung di sekitar lama multiline. Jika tidak ada tanda kurung, definisi lambda serakah. Jadi lambda masuk
mengembalikan fungsi yang mengembalikan
(y*z, [1,2,3])
Tapi
cara
di mana func adalah lambda multiline yang mengembalikan y * z. Apakah itu bekerja?
sumber
map(func, [1,2,3])
dan yang paling bawah harus menjadi kesalahan karena fungsi peta tidak memiliki cukup argumen. Juga ada beberapa tanda kurung tambahan dalam kode.(Bagi siapa pun yang masih tertarik dengan topik tersebut.)
Pertimbangkan ini (termasuk penggunaan nilai pengembalian pernyataan dalam pernyataan lebih lanjut dalam lambda "multiline", meskipun jelek sampai muntah ;-)
sumber
state.clear()
karena argumen default hanya dibuat sekali ketika fungsi dibuat.Anda cukup menggunakan slash (
\
) jika Anda memiliki banyak baris untuk fungsi lambda AndaContoh:
sumber
Saya mulai dengan python tetapi berasal dari Javascript cara yang paling jelas adalah mengekstrak ekspresi sebagai fungsi ....
Contoh yang dibuat, ekspresi multiply
(x*2)
diekstraksi sebagai fungsi dan karena itu saya bisa menggunakan multiline:https://repl.it/@datracka/python-lambda-function
Mungkin itu tidak menjawab pertanyaan yang tepat jika itu adalah bagaimana melakukan multiline dalam ekspresi lambda itu sendiri , tetapi jika seseorang mendapatkan utas ini mencari cara men-debug ekspresi (seperti saya), saya pikir itu akan membantu
sumber
map(multiply, [1, 2, 3])
?Mengenai peretasan jelek, Anda selalu dapat menggunakan kombinasi
exec
dan fungsi reguler untuk mendefinisikan fungsi multiline seperti ini:Anda dapat membungkus ini menjadi fungsi seperti:
sumber
Saya hanya bermain sedikit untuk mencoba membuat pemahaman dict dengan mengurangi, dan muncul dengan hack liner yang satu ini:
Saya hanya mencoba melakukan hal yang sama seperti apa yang dilakukan dalam pemahaman dict Javascript ini: https://stackoverflow.com/a/11068265
sumber
Inilah implementasi yang lebih menarik dari lambda multi-jalur. Tidak mungkin untuk mencapai karena bagaimana python menggunakan indentasi sebagai cara untuk menyusun kode.
Tapi untungnya bagi kami, pemformatan indent dapat dinonaktifkan menggunakan array dan tanda kurung.
Seperti yang sudah ditunjukkan beberapa orang, Anda dapat menulis kode seperti itu:
Secara teori jika Anda dijamin memiliki evaluasi dari kiri ke kanan itu akan berhasil tetapi Anda masih kehilangan nilai yang diteruskan dari satu ekspresi ke yang lain.
Salah satu cara untuk mencapai apa yang sedikit lebih bertele-tele adalah dengan memiliki
Di mana setiap lambda menerima argumen dari yang sebelumnya.
Metode ini memungkinkan Anda menulis sesuatu yang sedikit mirip / skema.
Jadi Anda dapat menulis hal-hal seperti ini:
Metode yang lebih kompleks dapat digunakan untuk menghitung sisi miring
Ini akan mengembalikan daftar angka skalar sehingga dapat digunakan untuk mengurangi beberapa nilai menjadi satu.
Memiliki banyak lambda tentu tidak akan menjadi sangat efisien tetapi jika Anda dibatasi itu bisa menjadi cara yang baik untuk menyelesaikan sesuatu dengan cepat maka tulis ulang sebagai fungsi yang sebenarnya nanti.
sumber
karena fungsi lambda seharusnya satu-baris, sebagai bentuk fungsi yang paling sederhana,
an entrance, then return
sumber