Saya mencoba belajar python dan menemukan beberapa kode yang bagus dan pendek tetapi tidak sepenuhnya masuk akal
konteksnya adalah:
def fn(*args):
return len(args) and max(args)-min(args)
Saya mengerti apa yang dilakukannya, tetapi mengapa python melakukan ini - yaitu mengembalikan nilai daripada Benar / Salah?
10 and 7-2
mengembalikan 5. Demikian pula, mengubah dan ke atau akan mengakibatkan perubahan fungsionalitas. Begitu
10 or 7 - 2
Akan kembali 10.
Apakah ini gaya yang sah / dapat diandalkan, atau adakah alasan lain dalam hal ini?
python
operators
logical-operators
Marcin
sumber
sumber
and
(sertaor
) tidak dibatasi untuk bekerja dengan, atau mengembalikan nilai boolean.None
atau pengecualian)0
Anda tidak dapat mengetahui apakahargs
kosong atau tidak kosong tetapi memiliki semua elemen yang sama.Jawaban:
TL; DR
Kami mulai dengan meringkas dua perilaku dari dua operator logika
and
danor
. Idiom ini akan menjadi dasar pembahasan kita di bawah ini.Perilaku tersebut juga diringkas dalam dokumen , terutama dalam tabel ini:
Satu-satunya operator yang mengembalikan nilai boolean terlepas dari operannya adalah
not
operator.Evaluasi "Truthiness", dan "Truthy"
Pernyataan
Adalah cara singkat yang sangat
pythonic(dan bisa dibilang kurang terbaca) untuk mengatakan "jikaargs
tidak kosong, kembalikan hasilmax(args) - min(args)
", jika tidak kembalikan0
. Secara umum, ini adalah representasiif-else
ekspresi yang lebih ringkas . Sebagai contoh,Harus (secara kasar) diterjemahkan ke:
Atau, dengan kata lain,
Demikian pula,
Setara dengan,
Di mana
exp1
danexp2
merupakan objek python sewenang-wenang, atau ekspresi yang mengembalikan beberapa objek. Kunci untuk memahami penggunaan logikaand
danor
operator di sini adalah memahami bahwa mereka tidak dibatasi untuk beroperasi pada, atau mengembalikan nilai boolean. Objek apa pun dengan nilai kebenaran dapat diuji di sini. Ini termasukint
,str
,list
,dict
,tuple
,set
,NoneType
, dan ditetapkan pengguna objek. Aturan korsleting masih berlaku juga.Tapi apakah kebenaran itu?
Ini mengacu pada bagaimana objek dievaluasi ketika digunakan dalam ekspresi bersyarat. @Patrick Haugh merangkum kebenaran dengan baik dalam posting ini .
Bagaimana
and
BekerjaKami membangun pertanyaan OP sebagai segue menjadi diskusi tentang bagaimana operator ini dalam hal ini.
Menemukan minimum dan maksimum itu mudah (gunakan fungsi bawaan!). Satu-satunya halangan di sini adalah menangani kasus sudut dengan tepat di mana daftar argumen bisa kosong (misalnya, memanggil
foo()
). Kami dapat melakukan keduanya dalam satu baris berkatand
operator:Karena
and
digunakan, ekspresi kedua juga harus dievaluasi jika yang pertama adalahTrue
. Perhatikan bahwa, jika ekspresi pertama dievaluasi kebenarannya, nilai yang dikembalikan selalu merupakan hasil dari ekspresi kedua . Jika ekspresi pertama dievaluasi sebagai Falsy, maka hasil yang dikembalikan adalah hasil dari ekspresi pertama.Dalam fungsi di atas, Jika
foo
menerima satu atau lebih argumen,len(args)
lebih besar dari0
(bilangan positif), jadi hasil yang dikembalikan adalahmax(args) - min(args)
. OTOH, jika tidak ada argumen yang dilewatkan,len(args)
adalah0
yang Falsy, dan0
dikembalikan.Perhatikan bahwa cara alternatif untuk menulis fungsi ini adalah:
Atau, lebih tepatnya,
Tentu saja, tidak ada dari fungsi ini yang melakukan pemeriksaan tipe apa pun, jadi kecuali Anda benar-benar mempercayai masukan yang diberikan, jangan mengandalkan kesederhanaan konstruksi ini.
Bagaimana
or
BekerjaSaya menjelaskan cara kerja
or
dengan cara yang sama dengan contoh yang dibuat-buat.Kami biasa
or
menangani kasus sudut di sini. Kami mendefinisikanfoo
sebagai:foo
melakukan penyaringan pada daftar untuk mempertahankan semua nomor9000
. Jika ada angka-angka seperti itu, hasil dari pemahaman daftar adalah daftar yang tidak kosong yaitu Truthy, jadi dikembalikan (korsleting dalam tindakan di sini). Jika tidak ada nomor tersebut, maka hasil dari daftar comp[]
adalah Falsy. Jadi ekspresi kedua sekarang dievaluasi (string yang tidak kosong) dan dikembalikan.Menggunakan kondisional, kita bisa menulis ulang fungsi ini sebagai,
Seperti sebelumnya, struktur ini lebih fleksibel dalam hal penanganan error.
sumber
if ... else (if ... else (if ... else (if ... else ...)))
bisa juga ditulis ulang... and ... and ... and ... and ...
dan pada saat itu menjadi sulit untuk membantah keterbacaan untuk kedua kasus.Mengutip dari Python Docs
Jadi, beginilah cara Python dirancang untuk mengevaluasi ekspresi boolean dan dokumentasi di atas memberi kita wawasan tentang mengapa mereka melakukannya.
Untuk mendapatkan nilai boolean cukup ketik saja.
Mengapa?
Hubungan arus pendek.
Sebagai contoh:
Hal yang sama juga berlaku
or
, yaitu, ia akan mengembalikan ekspresi yang Truthy segera setelah menemukannya, karena mengevaluasi sisa ekspresi itu berlebihan.Alih-alih mengembalikan hardcore
True
atauFalse
, Python mengembalikan Truthy atau Falsey , yang bagaimanapun juga akan mengevaluasi keTrue
atauFalse
. Anda dapat menggunakan ekspresi apa adanya, dan ini akan tetap berfungsi.Untuk mengetahui apa itu Truthy and Falsey , periksa jawaban Patrick Haugh
sumber
dan dan atau menjalankan logika boolean, tetapi mengembalikan salah satu nilai aktual saat dibandingkan. Saat menggunakan dan , nilai dievaluasi dalam konteks boolean dari kiri ke kanan. 0, '', [], (), {}, dan None salah dalam konteks boolean; segalanya benar.
Jika semua nilai benar dalam konteks boolean, dan mengembalikan nilai terakhir.
Jika ada nilai yang salah dalam konteks boolean dan mengembalikan nilai salah pertama.
Jadi kodenya
mengembalikan nilai
max(args)-min(args)
ketika ada args lain yang dikembalikannyalen(args)
yaitu 0.sumber
Ini sah, ini adalah evaluasi sirkuit pendek di mana nilai terakhir dikembalikan.
Anda memberikan contoh yang baik. Fungsi akan kembali
0
jika tidak ada argumen yang diteruskan, dan kode tidak harus memeriksa kasus khusus dari tidak ada argumen yang diteruskan.Cara lain untuk menggunakan ini, adalah dengan default argumen None ke primitif bisa berubah, seperti daftar kosong:
Jika beberapa nilai non-kebenaran diteruskan ke
alist
default ke daftar kosong, cara praktis untuk menghindariif
pernyataan dan perangkap argumen default yang bisa berubahsumber
Gotchas
Ya, ada beberapa gotcha.
fn() == fn(3) == fn(4, 4)
Pertama, jika
fn
kembali0
, Anda tidak dapat mengetahui apakah itu dipanggil tanpa parameter apa pun, dengan satu parameter atau dengan beberapa parameter yang sama:Apa
fn
maksudnyaKemudian, Python adalah bahasa dinamis. Itu tidak ditentukan di mana pun apa
fn
, apa inputnya dan seperti apa outputnya. Oleh karena itu, sangat penting untuk memberi nama fungsi dengan benar. Demikian pula, argumen tidak harus dipanggilargs
.delta(*numbers)
ataucalculate_range(*numbers)
mungkin menjelaskan lebih baik apa fungsi yang seharusnya dilakukan.Kesalahan argumen
Akhirnya,
and
operator logika seharusnya mencegah fungsi gagal jika dipanggil tanpa argumen apa pun. Itu masih gagal jika beberapa argumen bukan angka, meskipun:Alternatif yang memungkinkan
Berikut adalah cara menulis fungsi menurut "Lebih mudah meminta maaf daripada izin." prinsip :
Sebagai contoh:
Jika Anda benar-benar tidak ingin memunculkan pengecualian saat
delta
dipanggil tanpa argumen apa pun, Anda dapat mengembalikan beberapa nilai yang tidak dapat dilakukan sebaliknya (misalnya-1
atauNone
):sumber
Saya ingin menambahkan pada pertanyaan ini bahwa ini tidak hanya sah dan dapat diandalkan tetapi juga sangat praktis. Berikut ini contoh sederhananya:
Oleh karena itu, Anda benar-benar dapat menggunakannya untuk keuntungan Anda. Agar lebih berhati-hati, inilah cara saya melihatnya:
Or
operatorOperator Python
or
mengembalikan nilai Truth-y pertama, atau nilai terakhir, dan berhentiAnd
operatorOperator Python
and
mengembalikan nilai False-y pertama, atau nilai terakhir, dan berhentiDi balik layar
Dalam python, semua angka diartikan sebagai
True
kecuali 0. Oleh karena itu, mengatakan:sama dengan:
Yang jelas
False
. Oleh karena itu logis bahwa ia mengembalikan 0sumber
Iya. Ini adalah perilaku dan perbandingan yang benar.
Setidaknya dalam Python,
A and B
pengembalianB
jikaA
pada dasarnyaTrue
termasuk jikaA
TIDAK Null, TIDAKNone
TIDAK wadah kosong (seperti kosonglist
,dict
, dll).A
dikembalikan IFFA
pada dasarnyaFalse
atauNone
atau Kosong atau Null.Di sisi lain,
A or B
pengembalianA
jikaA
pada dasarnyaTrue
termasuk jikaA
TIDAK Null, TIDAKNone
TIDAK wadah kosong (seperti kosonglist
,dict
, dll), jika tidak maka kembaliB
.Sangat mudah untuk tidak memperhatikan (atau mengabaikan) perilaku ini karena, dalam Python, setiap objek
non-null
tidak kosong yang dievaluasi ke True diperlakukan seperti boolean.Misalnya, semua yang berikut akan mencetak "Benar"
Di sisi lain, semua yang berikut akan mencetak "False"
sumber
A
pada dasarnyaTrue
. Diperbaiki.untuk memahami dengan cara yang sederhana,
DAN:
if first_val is False return first_val else second_value
misalnya:
tapi,
dan => jika ada yang salah, itu akan menjadi salah. jika keduanya benar maka hanya itu yang akan menjadi kenyataan
ATAU :
if first_val is False return second_val else first_value
alasannya adalah, jika yang pertama salah maka periksa apakah 2 benar atau tidak.
misalnya:
tapi,
atau => jika ada yang salah, itu akan benar. jadi jika nilai pertama salah tidak peduli berapa nilai 2 yang seharusnya. sehingga mengembalikan nilai kedua apa pun yang bisa.
jika ada yang benar maka itu akan menjadi kenyataan. jika keduanya salah maka itu akan menjadi salah.
sumber