Operator walrus dan pendalaman f-string

Operator walrus := dan pendalaman f-string, termasuk nesting dan penentu = untuk debugging.

Daftar isi

Operator walrus := menugaskan nilai ke sebuah variabel sekaligus mengembalikan nilai itu sebagai hasil ekspresi, sehingga penugasan dapat diselipkan di tengah kondisi dan filter. Sementara itu, f-string memiliki bahasa penentu format yang melampaui konversi sederhana, mulai dari perataan, presisi, penentu = untuk debugging, hingga penentu bersarang. Topik ini membahas kedua fitur tersebut beserta perilaku halusnya pada Python 3.12.

Operator walrus diperkenalkan melalui PEP 572 pada Python 3.8 dengan nama resmi assignment expression. Berbeda dengan penugasan biasa, bentuk (variabel := nilai) berupa ekspresi yang memiliki nilai, sehingga dapat ditempatkan di tempat yang tidak menerima pernyataan penugasan, misalnya kondisi while.

python Contoh: walrus pada kondisi while
angka = [3, 9, 4, 12, 7]
batas = 10
indeks = 0
while (nilai := angka[indeks]) < batas:
    print(nilai, "masih di bawah batas")
    indeks += 1

print("perulangan berhenti pada", nilai)
text Keluaran
3 masih di bawah batas
9 masih di bawah batas
4 masih di bawah batas
perulangan berhenti pada 12

Tanpa walrus, pola ini menuntut penugasan nilai sebelum perulangan dan sekali lagi di badan perulangan, sehingga ekspresi penentu ditulis dua kali. Dengan walrus, nilai yang diuji pada kondisi tersimpan langsung dan tetap terjangkau setelah perulangan selesai, yaitu 12 pada contoh di atas. Tanda kurung pada (nilai := ...) bersifat lazim karena sebagian konteks menuntutnya demi menghindari kebingungan dengan operator perbandingan.

Walrus di dalam comprehension#

Kegunaan walrus yang paling sering dipakai adalah menyaring dan memakai hasil komputasi yang sama dalam satu langkah pada comprehension. Tanpa walrus, ekspresi perlu dihitung dua kali, yaitu sekali pada filter dan sekali pada elemen keluarannya.

python Contoh: walrus pada filter comprehension
data = [4, -7, 9, -2, 5]
positif = [y for x in data if (y := x * 2) > 0]
print(positif)
text Keluaran
[8, 18, 10]

Ekspresi x * 2 dihitung sekali per elemen, hasilnya ditugaskan ke y untuk diuji pada filter, dan y yang lolos langsung dipakai sebagai elemen hasil. Perilaku kebocoran lingkup yang disebut pada catatan di atas dapat diamati pada contoh berikut, ketika y masih terbaca setelah comprehension berakhir.

python Contoh: variabel walrus tetap hidup setelah comprehension
data = [1, 2, 3]
hasil = [y for x in data if (y := x) > 1]
print(hasil, y)
text Keluaran
[2, 3] 3

Variabel y menyimpan 3, yaitu nilai dari iterasi terakhir yang lolos filter, karena penugasan walrus terjadi pada lingkup luar. Sifat ini berguna untuk membaca hasil terakhir, tetapi juga berarti nama y tertimpa tanpa peringatan, sehingga pemakaiannya perlu dijaga agar tidak bertabrakan dengan variabel lain.

Penentu format pada f-string#

F-string mengikuti format specification mini language yang sama dengan str.format(). Penentu format ditulis setelah titik dua di dalam kurung kurawal dan mengatur presisi, pemisah ribuan, persentase, serta perataan dengan lebar tertentu.

python Contoh: penentu format umum
pi = 3.14159
harga = 1234567.891
persen = 0.875
teks = "kiri"
print(f"{pi:.2f}")
print(f"{harga:,.2f}")
print(f"{persen:.1%}")
print(f"[{teks:<10}]")
print(f"[{teks:>10}]")
print(f"[{teks:^10}]")
text Keluaran
3.14
1,234,567.89
87.5%
[kiri      ]
[      kiri]
[   kiri   ]

Penentu .2f membulatkan ke dua angka desimal, penentu ,.2f menambahkan koma ribuan di atasnya, dan penentu .1% mengalikan dengan 100 lalu menambahkan tanda persen. Perataan memakai <, >, dan ^ diikuti lebar total, yang pada contoh di atas bernilai sepuluh karakter. Lebar itu sendiri boleh berasal dari variabel melalui penentu bersarang, karena bagian di dalam penentu format juga boleh memuat kurung kurawal.

python Contoh: penentu format bersarang
lebar = 12
presisi = 3
nilai = 3.14159265
print(f"[{nilai:{lebar}.{presisi}f}]")
text Keluaran
[       3.142]

Penentu {lebar}.{presisi}f menyalin nilai lebar dan presisi dari lingkup sekitar pada saat f-string dibangun, sehingga format dapat dikonfigurasi saat program berjalan. Fitur ini berguna ketika lebar kolom laporan disesuaikan dengan data, tanpa perlu menyusun string format secara manual lewat penggabungan.

Kutipan bersarang dan penentu = untuk debugging#

Sejak Python 3.12, f-string boleh memakai tanda kutip yang sama dengan string luarnya, sehingga akses kunci dictionary tidak lagi memaksa pergantian kutip. Selain itu, penentu = memuat teks ekspresi beserta nilai terhitungnya dalam satu cetakan, yang sangat cocok untuk pelacakan cepat tanpa debugger.

python Contoh: kutipan yang sama sejak Python 3.12
kata = {"nama": "Citra"}
print(f"Salam untuk {kata["nama"]}")
text Keluaran
Salam untuk Citra

Pada versi sebelum 3.12, baris di atas perlu ditulis dengan kutip tunggal untuk kuncinya. Aturan lama itu tetap sah, sehingga kode yang sudah ada tidak perlu diubah, dan pilihannya kini menjadi soal konsistensi gaya dalam satu proyek.

python Contoh: penentu = untuk debugging
nilai = 42
nama = "Citra"
print(f"{nilai=}")
print(f"{nilai = }")
print(f"{nama=}")
print(f"{nilai * 2 = }")
text Keluaran
nilai=42
nilai = 42
nama='Citra'
nilai * 2 = 84

Penentu = mencetak teks ekspresi apa adanya, tanda sama dengan, lalu nilai kembalinya dalam bentuk repr(), yang tampak dari tanda kutip pada 'Citra'. Spasi yang ditulis sebelum = ikut disalin, sehingga f"{nilai = }" menghasilkan baris dengan spasi di kedua sisi tanda sama dengan. Ekspresi arbitrer seperti nilai * 2 juga didukung, bukan hanya nama variabel.

Kesalahan umum#

Kesalahan pertama adalah lupa awalan f. String biasa tidak menafsirkan kurung kurawal, sehingga seluruh ekspresi tercetak mentah tanpa pesan error apa pun.

python Contoh: string tanpa awalan f
nilai = 42
print("{nilai=}")
text Keluaran
{nilai=}

Perbaikannya cukup menambahkan awalan f pada string, dan cetakannya berubah menjadi nilai=42. Kesalahan serupa juga muncul ketika argumen untuk str.format() tidak diberikan, sehingga disiplin memeriksa awalan string layak dibiasakan.

Kesalahan kedua adalah menulis walrus di tempat yang hanya menerima pernyataan, tanpa tanda kurung yang mengikatnya menjadi ekspresi. Bentuk seperti itu ditolak interpreter saat berkas dibaca, bukan saat dijalankan.

python
# tidak-dijalankan
# walrus telanjang pada tingkat pernyataan memicu SyntaxError saat berkas dibaca
x := 5

Perbaikannya adalah membungkus penugasan dengan tanda kurung, seperti (x := 5) yang kini sah sebagai ekspresi, atau kembali ke pernyataan penugasan biasa x = 5 bila hasil ekspresi memang tidak dibutuhkan.

Ringkasan#

  • Operator walrus (v := nilai) menugaskan dan mengembalikan nilai sekaligus, sehingga kondisi while dan filter comprehension tidak perlu mengulang ekspresinya.
  • Walrus di dalam comprehension menugaskan ke lingkup fungsi luarnya, sehingga variabelnya tetap terbaca setelah comprehension selesai.
  • Penentu format mengatur presisi, pemisah ribuan, persentase, dan perataan, dengan penentu bersarang yang membaca lebar dan presisi dari variabel.
  • Sejak Python 3.12, f-string menerima kutipan yang sama dengan string luarnya, dan penentu = mencetak teks ekspresi beserta nilai repr()-nya untuk debugging.

Referensi#