Saya memiliki beberapa pemahaman daftar dengan Python di mana setiap iterasi dapat menimbulkan pengecualian.
Misalnya , jika saya memiliki:
eggs = (1,3,0,3,2)
[1/egg for egg in eggs]
Saya akan mendapatkan ZeroDivisionError
pengecualian di elemen ke-3.
Bagaimana saya menangani pengecualian ini dan melanjutkan eksekusi pemahaman daftar?
Satu-satunya cara yang bisa saya pikirkan adalah dengan menggunakan fungsi helper:
def spam(egg):
try:
return 1/egg
except ZeroDivisionError:
# handle division by zero error
# leave empty for now
pass
Tapi ini terlihat agak merepotkan bagiku.
Apakah ada cara yang lebih baik untuk melakukan ini dengan Python?
Catatan: Ini adalah contoh sederhana (lihat " misalnya " di atas) yang saya buat karena contoh nyata saya memerlukan beberapa konteks. Saya tidak tertarik untuk menghindari kesalahan bagi dengan nol tetapi dalam menangani pengecualian dalam pemahaman daftar.
python
exception
list-comprehension
Nathan Fellman
sumber
sumber
[1/egg except ZeroDivisionError: None for egg in (1,3,0,3,2)]
. Tapi masih dalam mode draf. Naluri saya adalah bahwa itu tidak akan diterima. Ekspresi imho bisa menjadi terlalu berantakan (memeriksa beberapa pengecualian, memiliki kombinasi yang lebih kompleks (beberapa operator logika, pemahaman kompleks, dll)ndarray
dengan pengaturan yang sesuai dinp.seterr
. Itu akan menghasilkan1/0 = nan
. Tapi saya menyadari itu tidak menggeneralisasi situasi lain di mana kebutuhan ini muncul.Jawaban:
Tidak ada ekspresi bawaan dalam Python yang memungkinkan Anda mengabaikan pengecualian (atau mengembalikan nilai alternatif & c jika ada pengecualian), jadi tidak mungkin, secara harfiah, untuk "menangani pengecualian dalam pemahaman daftar" karena pemahaman daftar adalah ekspresi mengandung ekspresi lain, tidak lebih (yaitu, tidak pernyataan, dan hanya pernyataan yang dapat menangkap / mengabaikan / menangani pengecualian).
Panggilan fungsi adalah ekspresi, dan badan fungsi dapat menyertakan semua pernyataan yang Anda inginkan, jadi mendelegasikan evaluasi sub-ekspresi yang rentan terhadap pengecualian ke suatu fungsi, seperti yang Anda perhatikan, adalah salah satu solusi yang layak (yang lain, jika memungkinkan, adalah memeriksa nilai-nilai yang mungkin memicu pengecualian, seperti yang juga disarankan dalam jawaban lain).
Tanggapan yang benar untuk pertanyaan "bagaimana menangani pengecualian dalam pemahaman daftar" semuanya mengungkapkan sebagian dari semua kebenaran ini: 1) secara harfiah, yaitu secara leksikal DALAM pemahaman itu sendiri, Anda tidak bisa; 2) secara praktis, Anda mendelegasikan pekerjaan ke suatu fungsi atau memeriksa nilai-nilai rawan kesalahan jika memungkinkan. Klaim berulang Anda bahwa ini bukan jawaban dengan demikian tidak berdasar.
sumber
[x[1] for x in list except IndexError pass]
. Bisakah penerjemah membuat fungsi sementara untuk dicobax[1]
?Saya menyadari pertanyaan ini sudah cukup lama, tetapi Anda juga dapat membuat fungsi umum untuk mempermudah hal semacam ini:
Kemudian, dalam pemahaman Anda:
Anda tentu saja dapat membuat fungsi pegangan default apa pun yang Anda inginkan (katakanlah Anda lebih suka mengembalikan 'Tidak Ada' secara default).
Semoga ini bisa membantu Anda atau pemirsa pertanyaan ini di masa mendatang!
Catatan: di python 3, saya akan membuat kata kunci argumen 'handle' saja, dan meletakkannya di akhir daftar argumen. Ini akan membuat argumen yang lewat dan semacamnya melalui tangkapan jauh lebih alami.
sumber
args
dankwargs
melalui pegangan juga. Dengan cara itu Anda bisa mengembalikan kataegg
alih-alih hardcode0
, atau pengecualian seperti yang Anda lakukan.handle
setelah**kwarg
dan mendapatSyntaxError
. Apakah maksud Anda dereferensi sebagaikwargs.get('handle',e)
?Kamu bisa memakai
ini hanya akan melewatkan elemen yang nol.
sumber
Tidak, tidak ada cara yang lebih baik. Dalam banyak kasus, Anda dapat menggunakan penghindaran seperti yang dilakukan Peter
Pilihan Anda yang lain adalah tidak menggunakan pemahaman
Terserah Anda untuk memutuskan apakah itu lebih rumit atau tidak
sumber
Saya pikir fungsi pembantu, seperti yang disarankan oleh orang yang mengajukan pertanyaan awal dan juga Bryan Head, itu bagus dan tidak merepotkan sama sekali. Satu baris kode ajaib yang melakukan semua pekerjaan tidak selalu memungkinkan sehingga fungsi pembantu adalah solusi sempurna jika seseorang ingin menghindari
for
loop. Namun saya akan memodifikasinya menjadi yang ini:Outputnya akan seperti ini
[(1/1, None), (1/3, None), (None, ZeroDivisionError), (1/3, None), (1/2, None)]
. Dengan jawaban ini Anda memiliki kendali penuh untuk melanjutkan dengan cara apa pun yang Anda inginkan.sumber
Either
tipe dalam beberapa bahasa pemrograman fungsional (seperti Scala), di mana sebuahEither
dapat berisi nilai dari satu jenis atau lainnya, tetapi tidak keduanya. Satu-satunya perbedaan adalah bahwa dalam bahasa-bahasa tersebut adalah idiomatis untuk meletakkan kesalahan di sisi kiri dan nilai di sisi kanan. Berikut artikel dengan informasi lebih lanjut .Saya tidak melihat jawaban apapun menyebutkan ini. Tapi contoh ini akan menjadi salah satu cara untuk mencegah pengecualian dimunculkan untuk kasus gagal yang diketahui.
sumber