Câu 1Đoạn code sau in gì?items = [10, 20, 30]
if (n := len(items)) >= 2:
print(n)
Toán tử Walrus := để gán và kiểm tra trong một dòng
Học toán tử walrus := của Python 3.8 để vừa gán biến vừa kiểm tra điều kiện chỉ trong một dòng code gọn gàng.
Toán tử walrus := được giới thiệu trong Python 3.8 để cho phép bạn gán và kiểm tra trong một dòng. Hình dạng := nhìn giống răng nanh hải mã — và đó là lý do của tên gọi. Nó giúp giảm bớt code thừa khi cùng một giá trị được tái sử dụng bên trong điều kiện if hoặc while.
Cơ bản về toán tử walrus
= thông thường là một câu lệnh và không thể xuất hiện bên trong biểu thức — vì vậy bạn không thể đặt nó trong điều kiện của if hoặc while. := là một biểu thức, nên nó có thể đặt trực tiếp bên trong điều kiện.
Với biến := biểu_thức, bạn gán kết quả vào biến và dùng chính giá trị đó làm giá trị của điều kiện.
Cột trái (thường) viết phép gán và phép kiểm tra trên các dòng riêng. Cột phải (walrus) gán và kiểm tra trong một điều kiện duy nhất.
# Cách thường (hai dòng)
cart = ["táo", "bánh mì", "sữa", "trứng"]
n = len(cart)
if n >= 3:
print(f"{n} món: miễn phí vận chuyển")
# Phiên bản walrus (một dòng: gán + kiểm tra)
if (n := len(cart)) >= 3:
print(f"{n} món: miễn phí vận chuyển")
# Kết quả: 4 món: miễn phí vận chuyển
Bọc nó trong dấu ngoặc đơn khi đặt trong điều kiện
if n := len(cart) >= 3: không có dấu ngoặc đơn sẽ đánh giá len(cart) >= 3 trước và gán True/False vào n. Cách viết chuẩn là (n := len(cart)) >= 3 — bọc phép gán trong dấu ngoặc đơn.
Dùng toán tử walrus với if
Một mẫu phổ biến trong if là cần giá trị đã kiểm tra cả bên trong thân. Thông thường bạn phải tách "gán, rồi kiểm tra" ra hai dòng, nhưng toán tử walrus cho phép bạn viết một lần, ngay tại nơi giá trị được cần".
# Rẽ nhánh dựa trên số lượng kết quả tìm kiếm, rồi dùng nó trong thân
search_results = ["Sách A", "Sách B", "Sách C", "Sách D", "Sách E"]
if (hit_count := len(search_results)) >= 3:
print(f"Tìm thấy {hit_count} kết quả")
else:
print("Quá ít kết quả")
# Kết quả: Tìm thấy 5 kết quả
Dùng toán tử walrus với while
Trong while, walrus tỏa sáng khi bạn muốn giá trị được lấy ra vừa làm điều kiện vừa là thứ bạn dùng bên trong thân.
Mỗi vòng lặp kiểm tra xem hàng đợi có rỗng không trước. Nếu rỗng, đánh giá ngắn mạch bỏ qua pop() và thoát vòng lặp. Ngược lại queue.pop(0) lấy phần tử đầu và gán vào task, rồi thân chạy với task trước khi lặp lại.
# Làm sạch hàng đợi từng phần tử một từ đầu
pending_jobs = ["gửi email", "sao lưu", "triển khai"]
while pending_jobs and (job := pending_jobs.pop(0)):
print(f"đang xử lý: {job}")
# đang xử lý: gửi email / đang xử lý: sao lưu / đang xử lý: triển khai
# Ngay khi pending_jobs trở thành rỗng, vế trái đánh giá False và pop() bị bỏ qua — vòng lặp thoát.
pending_jobs and (job := pending_jobs.pop(0)) thoát vòng lặp qua đánh giá ngắn mạch ngay khi vế trái rỗng (False). Điều đó tránh bug gọi pop() trên list rỗng và kích hoạt IndexError.
Khi nào nên dùng và khi nào không
Toán tử walrus không thêm khả năng gì ngoài việc tiết kiệm số ký tự gõ. Viết logic trên một dòng thì tiện, nhưng cũng có thể gây khó đọc, nên hãy chọn lọc khi dùng.
| Tình huống | Khuyến nghị | Tại sao |
|---|---|---|
| Tái sử dụng giá trị được kiểm tra bên trong thân | Nên dùng | Tách hai dòng đặt biến xa nơi nó được dùng |
| Trong while, dùng giá trị pop ra vừa làm điều kiện vừa dùng trong thân | Nên dùng | Kết hợp điều kiện thoát của vòng lặp với việc lấy ra |
| Tính toán phức tạp hoặc tác dụng phụ trong điều kiện | Tránh | Giấu công việc trong biểu thức khiến luồng khó theo dõi |
| Chỉ là phép gán đơn thuần không có điều kiện | Không dùng | `=` thường đơn giản và dễ đọc hơn |
Trong bài này bạn đã học cách dùng toán tử walrus := để kết hợp phép gán và kiểm tra thành một biểu thức duy nhất.
Kiểm tra kiến thức
Hãy trả lời từng câu hỏi một.
Câu 2Cách nào là đúng để dùng toán tử walrus bên trong điều kiện if?
Câu 3Câu nào mô tả tốt nhất toán tử walrus :=?