TL; DR
Kami mulai dengan meringkas dua perilaku dari dua operator logika and
dan or
. Idiom ini akan menjadi dasar pembahasan kita di bawah ini.
and
Kembalikan nilai Falsy pertama jika ada, jika tidak kembalikan nilai terakhir dalam ekspresi.
or
Kembalikan nilai Truthy pertama jika ada, jika tidak kembalikan nilai terakhir dalam ekspresi.
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
len(args) and max(args) - min(args)
Adalah cara singkat yang sangat pythonic (dan bisa dibilang kurang terbaca) untuk mengatakan "jika args
tidak kosong, kembalikan hasil max(args) - min(args)
", jika tidak kembalikan 0
. Secara umum, ini adalah representasi if-else
ekspresi yang lebih ringkas . Sebagai contoh,
exp1 and exp2
Harus (secara kasar) diterjemahkan ke:
r1 = exp1
if r1:
r1 = exp2
Atau, dengan kata lain,
r1 = exp1 if exp1 else exp2
Demikian pula,
exp1 or exp2
Setara dengan,
r1 = exp1
if not r1:
r1 = exp2
Di mana exp1
dan exp2
merupakan objek python sewenang-wenang, atau ekspresi yang mengembalikan beberapa objek. Kunci untuk memahami penggunaan logika and
dan or
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 termasuk int
, 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 .
Semua nilai dianggap "benar" kecuali yang berikut ini, yang "salah":
None
False
0
0.0
0j
Decimal(0)
Fraction(0, 1)
[]
- kosong list
{}
- kosong dict
()
- kosong tuple
''
- kosong str
b''
- kosong bytes
set()
- kosong set
- kosong
range
, sepertirange(0)
- objek yang
obj.__bool__()
kembali False
obj.__len__()
kembali 0
Nilai "kebenaran" akan memenuhi pemeriksaan yang dilakukan oleh
pernyataan if
atau while
. Kami menggunakan "kebenaran" dan "salah" untuk membedakan dari
bool
nilai True
dan False
.
Bagaimana and
Bekerja
Kami membangun pertanyaan OP sebagai segue menjadi diskusi tentang bagaimana operator ini dalam hal ini.
Diberikan fungsi dengan definisi
def foo(*args):
...
Bagaimana cara mengembalikan perbedaan antara nilai minimum dan maksimum dalam daftar nol atau lebih argumen?
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 berkat and
operator:
def foo(*args):
return len(args) and max(args) - min(args)
foo(1, 2, 3, 4, 5)
# 4
foo()
# 0
Karena and
digunakan, ekspresi kedua juga harus dievaluasi jika yang pertama adalah True
. 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 dari 0
(bilangan positif), jadi hasil yang dikembalikan adalah max(args) - min(args)
. OTOH, jika tidak ada argumen yang dilewatkan, len(args)
adalah 0
yang Falsy, dan 0
dikembalikan.
Perhatikan bahwa cara alternatif untuk menulis fungsi ini adalah:
def foo(*args):
if not len(args):
return 0
return max(args) - min(args)
Atau, lebih tepatnya,
def foo(*args):
return 0 if not args else max(args) - min(args)
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
Bekerja
Saya menjelaskan cara kerja or
dengan cara yang sama dengan contoh yang dibuat-buat.
Diberikan fungsi dengan definisi
def foo(*args):
...
Bagaimana Anda menyelesaikan foo
untuk mengembalikan semua angka 9000
?
Kami biasa or
menangani kasus sudut di sini. Kami mendefinisikan foo
sebagai:
def foo(*args):
return [x for x in args if x > 9000] or 'No number over 9000!'
foo(9004, 1, 2, 500)
# [9004]
foo(1, 2, 3, 4)
# 'No number over 9000!'
foo
melakukan penyaringan pada daftar untuk mempertahankan semua nomor 9000
. 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,
def foo(*args):
r = [x for x in args if x > 9000]
if not r:
return 'No number over 9000!'
return r
Seperti sebelumnya, struktur ini lebih fleksibel dalam hal penanganan error.
and
(sertaor
) tidak dibatasi untuk bekerja dengan, atau mengembalikan nilai boolean.