Mục lục
Vì sao cần rẽ nhánh
Tới giờ các chương trình bạn viết đều chạy tuần tự: dòng trên xuống dòng dưới, không có quyết định nào. Trong thực tế, chương trình thường phải chọn làm việc này hay việc kia tuỳ vào dữ liệu đầu vào.
Vài ví dụ rất sát với AI / data:
- Nếu
accuracy< 0.7 thì retrain model, ngược lại deploy. - Nếu giá trị bị thiếu (
None) thì điền mặc định, ngược lại giữ nguyên. - Nếu input của user là số âm thì báo lỗi, ngược lại tiếp tục tính.
Tất cả những "nếu... thì... ngược lại..." trên đều được viết bằng if / elif / else. Đây là cấu trúc rẽ nhánh phổ biến nhất trong mọi ngôn ngữ lập trình, và Python có cú pháp gọn nhất.
Cú pháp if cơ bản
Cấu trúc tối giản:
if <điều kiện>:
<khối lệnh sẽ chạy nếu điều kiện đúng>
3 thành phần cần nhớ:
- Từ khoá
ifở đầu dòng. - Một biểu thức điều kiện trả về
TruehoặcFalse(xem lại bài 6 về toán tử so sánh và logic). - Dấu hai chấm
:ở cuối dòngif, sau đó là block code được thụt vào.
Ví dụ kiểm tra một số có lớn hơn 0:
# Bai-7/example_01.py
x = 5
if x > 0:
print("x là số dương")
print("Tiếp tục xử lý...")
print("Dòng này luôn chạy, không phụ thuộc if")
Output:
x là số dương
Tiếp tục xử lý...
Dòng này luôn chạy, không phụ thuộc if
Hai dòng print bên trong if chỉ chạy khi x > 0 là True. Dòng cuối cùng không thụt vào nên không thuộc block if — nó luôn chạy.
Indentation 4 spaces trong Python
Khác với C, Java hay JavaScript dùng cặp { } để gom block, Python dùng chính độ thụt dòng (indentation) để xác định block. Cùng mức thụt = cùng một block.
Ví dụ so sánh:
// JavaScript dùng { }
if (x > 0) {
console.log("dương");
console.log("done");
}
# Python dùng indentation
if x > 0:
print("dương")
print("done")
Quy ước chính thức (PEP 8):
- Dùng 4 spaces cho mỗi cấp thụt dòng.
- Không trộn tab và space trong cùng một file — Python 3 sẽ báo
TabError. - Tất cả các dòng trong cùng một block phải thụt vào cùng số lượng space.
Nếu thụt sai, Python báo IndentationError ngay khi parse:
# Bai-7/example_02_indent_error.py
x = 5
if x > 0:
print("dương")
print("sai mức thụt") # 3 spaces — IndentationError
IndentationError: unindent does not match any outer indentation level
Mọi editor cho Python (VS Code, PyCharm, JupyterLab) đều cấu hình mặc định Tab = 4 spaces, nên thường bạn chỉ cần nhấn Tab và editor tự chèn 4 spaces.
else — nhánh ngược lại
Khi cần chạy block code khác trong trường hợp điều kiện sai, dùng else:
if <điều kiện>:
<chạy khi điều kiện đúng>
else:
<chạy khi điều kiện sai>
Ví dụ kiểm tra tuổi:
# Bai-7/example_03.py
age = 17
if age >= 18:
print("Bạn đủ tuổi đăng ký")
else:
print("Bạn chưa đủ 18 tuổi")
Output với age = 17:
Bạn chưa đủ 18 tuổi
else không có điều kiện đi kèm — nó tự hiểu là "trong các trường hợp còn lại". Một if chỉ có thể có tối đa một else, và else luôn đứng cuối.
elif — nhiều điều kiện theo thứ tự
Khi có hơn 2 nhánh, dùng elif (viết tắt của "else if"). Python kiểm tra các điều kiện theo thứ tự từ trên xuống và chỉ chạy block của điều kiện đúng đầu tiên; các điều kiện sau sẽ bị bỏ qua.
# Bai-7/example_04.py
score = 7.5
if score >= 9:
grade = "A"
elif score >= 8:
grade = "B"
elif score >= 6.5:
grade = "C"
elif score >= 5:
grade = "D"
else:
grade = "F"
print(f"Điểm {score} → xếp loại {grade}")
Output:
Điểm 7.5 → xếp loại C
Một số lưu ý quan trọng:
- Số lượng
elifkhông giới hạn, có thể có 0, 1, hoặc nhiều nhánh. elseở cuối là tuỳ chọn.- Thứ tự điều kiện ảnh hưởng kết quả. Vì
score = 7.5không thoả>= 9và>= 8, nên rơi vào>= 6.5và dừng tại đây. Nếu viết ngược lại (từ thấp lên cao) thì tất cả điểm >= 5 sẽ rơi vào nhánh đầu tiên — sai logic. - Python không có
switch / casetruyền thống. Từ Python 3.10 trở đi cómatch / case(structural pattern matching), nhưngelifvẫn là cách phổ biến nhất cho điều kiện giá trị.
Nested if — lồng nhau
Có thể đặt một if bên trong if khác, gọi là nested if. Khối bên trong sẽ thụt thêm 4 spaces nữa.
# Bai-7/example_05_nested.py
age = 25
has_license = True
if age >= 18:
if has_license:
print("Được phép lái xe")
else:
print("Đủ tuổi nhưng chưa có bằng lái")
else:
print("Chưa đủ tuổi lái xe")
Đoạn trên hoạt động đúng, nhưng nested if làm code khó đọc khi lồng quá sâu (3-4 cấp). Trong đa số trường hợp, ta có thể viết lại bằng toán tử and cho gọn hơn:
# Cách viết phẳng — dễ đọc hơn
if age >= 18 and has_license:
print("Được phép lái xe")
elif age >= 18 and not has_license:
print("Đủ tuổi nhưng chưa có bằng lái")
else:
print("Chưa đủ tuổi lái xe")
Nguyên tắc: ưu tiên cấu trúc phẳng, dùng nested if chỉ khi điều kiện bên trong thật sự không liên quan trực tiếp tới điều kiện bên ngoài.
Ternary expression
Khi cần gán giá trị dựa trên điều kiện, thay vì viết 4 dòng if / else, Python cho phép viết gọn trong 1 dòng — gọi là conditional expression (ternary expression):
value_if_true if condition else value_if_false
So sánh hai cách viết:
# Cách dài
age = 20
if age >= 18:
status = "adult"
else:
status = "minor"
# Cách ngắn — ternary
status = "adult" if age >= 18 else "minor"
print(status) # adult
Ternary phù hợp khi:
- Cả hai nhánh đều trả về một giá trị để gán cho biến.
- Logic đơn giản, không cần > 1 dòng cho mỗi nhánh.
Nếu logic phức tạp hoặc cần chạy nhiều lệnh trong mỗi nhánh, vẫn nên dùng if / else nhiều dòng cho dễ đọc.
Truthy / Falsy values
Trong if <điều kiện>, điều kiện không bắt buộc phải là kết quả của phép so sánh. Python chấp nhận mọi giá trị rồi tự ép kiểu sang bool. Các giá trị được coi là falsy (tương đương False) trong Python 3:
False- Số bằng 0:
0,0.0,0j - Chuỗi rỗng:
"" - Collection rỗng:
[],(),{},set() None
Mọi giá trị khác đều là truthy — kể cả số âm, chuỗi "False" (vì là chuỗi có nội dung), list chứa một phần tử [0]...
# Bai-7/example_06_truthy.py
items = []
if items:
print(f"Có {len(items)} mục")
else:
print("Danh sách rỗng")
# Output: Danh sách rỗng
name = ""
if name:
print(f"Xin chào, {name}")
else:
print("Bạn chưa nhập tên")
# Output: Bạn chưa nhập tên
Viết if items: ngắn gọn hơn if len(items) > 0: và là idiom chuẩn trong Python. Có thể kiểm tra rõ ràng bằng bool(x):
print(bool(0)) # False
print(bool("")) # False
print(bool([])) # False
print(bool(None)) # False
print(bool("hi")) # True
print(bool([0])) # True — list có 1 phần tử
print(bool(-1)) # True — số khác 0 là truthy
== None vs is None
Một pitfall hay gặp khi mới học Python: dùng == để so sánh với None. Cả hai cú pháp sau đều chạy được:
x = None
if x == None: # chạy được nhưng không khuyến nghị
print("x là None")
if x is None: # khuyến nghị
print("x là None")
Khác biệt:
==kiểm tra giá trị bằng nhau, gọi method__eq__. Object tự định nghĩa có thể override__eq__để trảTruekhi so vớiNone, gây kết quả bất ngờ.iskiểm tra cùng object trong bộ nhớ (so sánh địa chỉ). Vì Python chỉ có một objectNoneduy nhất (singleton),is Noneluôn cho kết quả chính xác và nhanh hơn.
PEP 8 chính thức khuyến nghị:
Comparisons to singletons like None should always be done with
isoris not, never the equality operators.
Tương tự khi check ngược lại:
if x is not None:
print(f"x có giá trị: {x}")
Quy tắc nhớ: chỉ so sánh với None, True, False bằng is / is not. Còn so sánh giá trị thường (số, chuỗi) thì dùng == / !=.
Bài tập
Bài 1: Phân loại số dương / âm / zero
Viết chương trình nhận một số từ input(), chuyển sang float, rồi in ra:
"dương"nếu số > 0,"âm"nếu số < 0,"zero"nếu số = 0.
Gợi ý khung code:
# Bai-7/bt1_phan_loai_so.py
x = float(input("Nhập một số: "))
if x > 0:
...
elif x < 0:
...
else:
...
Bài 2: Xếp loại BMI
BMI (Body Mass Index) tính theo công thức: BMI = cân_nặng (kg) / chiều_cao (m) ** 2. Viết chương trình:
- Nhận
weight(kg) vàheight(m) từinput(). - Tính BMI, làm tròn 2 chữ số thập phân.
- Xếp loại theo bảng của WHO:
BMI < 18.5 → "Thiếu cân"
18.5 <= BMI < 25 → "Bình thường"
25 <= BMI < 30 → "Thừa cân"
BMI >= 30 → "Béo phì"
Output mẫu:
Cân nặng (kg): 60
Chiều cao (m): 1.65
BMI = 22.04 → Bình thường
Gợi ý:
# Bai-7/bt2_bmi.py
weight = float(input("Cân nặng (kg): "))
height = float(input("Chiều cao (m): "))
bmi = weight / (height ** 2)
bmi = round(bmi, 2)
if bmi < 18.5:
label = "Thiếu cân"
elif bmi < 25:
label = "Bình thường"
elif bmi < 30:
label = "Thừa cân"
else:
label = "Béo phì"
print(f"BMI = {bmi} → {label}")
Bài tập mở rộng: thêm kiểm tra đầu vào — nếu weight <= 0 hoặc height <= 0 thì in "Dữ liệu không hợp lệ" và không tính BMI.
Tóm tắt
if <điều kiện>:chạy block bên dưới khi điều kiệnTrue.else:bắt các trường hợp còn lại;elifkiểm tra thêm điều kiện theo thứ tự từ trên xuống, dừng ở nhánh đúng đầu tiên.- Python dùng indentation 4 spaces thay cho
{ }; thụt sai sẽ báoIndentationError. - Nested if hoạt động được nhưng nên hạn chế > 2 cấp, ưu tiên gộp điều kiện bằng
and/or. - Ternary
a if cond else bphù hợp khi cần gán giá trị một dòng. - Falsy values trong Python:
False,0,0.0,"",[],(),{},None. Mọi giá trị khác là truthy. - So sánh với
Noneluôn dùngis None/is not None, không dùng==/!=.
Bài tiếp theo sẽ học vòng lặp for và hàm range — kỹ thuật lặp đi lặp lại một thao tác trên nhiều phần tử.
