Dalam C # ada operator penggabungan nol (ditulis sebagai ??
) yang memungkinkan untuk memeriksa nol dengan mudah (pendek) selama penugasan:
string s = null;
var other = s ?? "some default value";
Apakah ada yang setara dengan python?
Saya tahu bahwa saya dapat melakukan:
s = None
other = s if s else "some default value"
Tetapi apakah ada cara yang lebih pendek (di mana saya tidak perlu mengulangi s
)?
python
null-coalescing-operator
Klaus Byskov Pedersen
sumber
sumber
??
operator diusulkan sebagai PEP 505 .Jawaban:
Ok, harus diklarifikasi cara kerja
or
operator. Ini adalah operator boolean, jadi ia bekerja dalam konteks boolean. Jika nilainya bukan boolean, nilai tersebut dikonversi ke boolean untuk keperluan operator.Perhatikan bahwa
or
operator tidak hanya mengembalikanTrue
atauFalse
. Sebagai gantinya, ia mengembalikan operan pertama jika operan pertama bernilai true, dan mengembalikan operan kedua jika operan pertama bernilai false.Dalam kasus ini, ekspresi
x or y
kembalix
jika ituTrue
atau bernilai true ketika dikonversi ke boolean. Kalau tidak, ia kembaliy
. Untuk sebagian besar kasus, ini akan berfungsi untuk tujuan yang sama dari operator penggabungan nol C♯, tetapi perlu diingat:Jika Anda menggunakan variabel Anda
s
untuk menyimpan sesuatu yang merupakan referensi ke instance dari kelas atauNone
(selama kelas Anda tidak mendefinisikan anggota__nonzero__()
dan__len__()
), aman untuk menggunakan semantik yang sama dengan operator penggabungan nol.Bahkan, mungkin berguna untuk memiliki efek samping Python ini. Karena Anda tahu nilai apa yang bernilai false, Anda dapat menggunakan ini untuk memicu nilai default tanpa menggunakan
None
secara spesifik (objek kesalahan, misalnya).Dalam beberapa bahasa perilaku ini disebut sebagai operator Elvis .
sumber
s
merupakan nilai yang valid tetapi tidak benar? (Saya tidak tahu Python, jadi saya tidak yakin apakah konsep 'kebenaran' berlaku.)None
dan wadah kosong (termasuk string) dianggap salah, selain konstantaFalse
. Kebanyakan hal lain dianggap benar. Saya akan mengatakan bahwa bahaya utama di sini adalah bahwa Anda akan mendapatkan nilai yang benar tetapi non-string, tetapi itu tidak akan menjadi masalah dalam beberapa program.datetime.time(0)
ternyata juga falsy!Dengan ketat,
Kalau tidak,
s = False
akan menjadi"default value"
, yang mungkin bukan yang dimaksudkan.Jika Anda ingin mempersingkat ini, cobalah:
sumber
Consider x()?.y()?.z()
Berikut adalah fungsi yang akan mengembalikan argumen pertama yang tidak
None
:reduce()
mungkin perlu mengulangi semua argumen meskipun argumen pertama tidakNone
, jadi Anda juga dapat menggunakan versi ini:sumber
def coalesce(*arg): return next((a for a in arg if a is not None), None)
melakukan hal yang sama seperti contoh terakhir Anda dalam satu baris.Consider x()?.y()?.z()
Saya menyadari ini dijawab, tetapi ada opsi lain ketika Anda berurusan dengan objek.
Jika Anda memiliki objek yang mungkin:
Kamu bisa memakai:
Suka:
Dengan menambahkan
{}
sebagai nilai default, jika "nama" hilang, objek kosong dikembalikan dan diteruskan ke get berikutnya. Ini mirip dengan navigasi aman-nol di C #, yang akan sepertiobj?.name?.first
.sumber
.get
, ini hanya berfungsi untuk objek seperti dictgetattr()
.get
pada dict tidak menggunakan parameter default jika nilainya Tidak ada tetapi menggunakan parameter default jika nilai tidak ada karena kunci tidak ada dalam dict.{'a': None}.get('a', 'I do not want None')
masih akan memberi AndaNone
hasilnya.Selain jawaban Juliano tentang perilaku "atau": "cepat"
Jadi terkadang itu mungkin jalan pintas yang berguna untuk hal-hal seperti
sumber
Selain jawaban @Bothwells (yang saya sukai) untuk nilai-nilai tunggal, untuk mengecek penetapan nilai fungsi kembali, Anda dapat menggunakan walrus-operator baru (karena python3.8):
Dengan demikian,
test
fungsi tidak perlu dievaluasi dua kali (seperti padaa = 2 if test() is None else test()
)sumber
Jika Anda perlu membuat sarang lebih dari satu operasi penggabungan nol seperti:
model?.data()?.first()
Ini bukan masalah yang mudah diselesaikan
or
. Ini juga tidak dapat dipecahkan dengan.get()
yang membutuhkan jenis kamus atau sejenisnya (dan tidak dapat disarangkan pula) ataugetattr()
yang akan mengeluarkan pengecualian ketika NoneType tidak memiliki atribut.Pip yang relevan yang mempertimbangkan menambahkan null penggabungan ke bahasa adalah PEP 505 dan diskusi yang relevan dengan dokumen ada di utas python-ideas .
sumber
Mengenai jawaban oleh @Hugh Bothwell, @mortehu dan @glglgl.
Setup Dataset untuk pengujian
Tetapkan implementasi
Buat fungsi tes
Hasil pada mac i7 @ 2.7Ghz menggunakan python 2.7
Jelas itu
not_none
fungsi menjawab pertanyaan OP dengan benar dan menangani masalah "falsy". Ini juga yang tercepat dan termudah untuk dibaca. Jika menerapkan logika di banyak tempat, itu jelas cara terbaik untuk pergi.Jika Anda memiliki masalah di mana Anda ingin menemukan nilai bukan nol pertama di iterable, maka respons @ mortehu adalah cara yang harus dilakukan. Tetapi ini adalah solusi untuk masalah yang berbeda dari OP, meskipun sebagian dapat menangani kasus itu. Itu tidak bisa mengambil nilai ANDER default. Argumen terakhir adalah nilai default yang dikembalikan, tetapi Anda tidak akan meneruskan iterable dalam kasus itu dan juga tidak eksplisit bahwa argumen terakhir adalah nilai default.
Anda kemudian dapat melakukan di bawah ini, tetapi saya masih akan menggunakan
not_null
untuk kasus penggunaan nilai tunggal.sumber
Bagi mereka seperti saya yang tersandung di sini mencari solusi yang layak untuk masalah ini, ketika variabel mungkin tidak terdefinisi, yang paling dekat saya dapatkan adalah:
Perhatikan bahwa string diperlukan saat memeriksa global, tetapi setelah itu variabel aktual digunakan saat memeriksa nilai.
Lebih lanjut tentang keberadaan variabel: Bagaimana cara saya memeriksa apakah ada variabel?
sumber
(variablename or False) == True
sama denganvariablename == True
Jika Anda tidak dapat menemukan nama di dalam kamus, itu akan mengembalikan nilai default_v, jika nama ada maka itu akan menambah nilai yang ada dengan 1.
Semoga ini bisa membantu
sumber
Dua fungsi di bawah ini saya temukan sangat berguna ketika berhadapan dengan banyak kasus pengujian variabel.
sumber