Nếu bạn chuyển sang Python từ Java, C# hay JavaScript, rất có thể bạn đang viết Python "theo giọng" của ngôn ngữ cũ: vòng lặp với chỉ số, kiểm tra kiểu thủ công, đóng mở file bằng tay. Code vẫn chạy, nhưng chưa tận dụng được sức mạnh của Python. Cộng đồng gọi phong cách viết tự nhiên, rõ ràng, đúng tinh thần ngôn ngữ là "Pythonic". Tinh thần đó được tóm gọn trong The Zen of Python (PEP 20), mà bạn có thể đọc ngay bằng lệnh import this. Dưới đây là 10 thủ thuật giúp code của bạn Pythonic hơn.

1. Lặp trực tiếp, dùng enumerate khi cần chỉ số

Thay vì for i in range(len(items)), hãy lặp trực tiếp trên phần tử. Khi cần cả chỉ số, dùng enumerate:

fruits = ["táo", "cam", "xoài"]
 
for index, fruit in enumerate(fruits, start=1):
    print(f"{index}. {fruit}")

2. Dùng zip để duyệt song song

Khi cần duyệt nhiều danh sách cùng lúc, zip gọn hơn hẳn việc truy cập theo chỉ số: for name, score in zip(names, scores). Từ Python 3.10, bạn có thể truyền strict=True để báo lỗi nếu các danh sách khác độ dài, tránh lỗi âm thầm.

3. List, dict, set comprehension

Comprehension giúp tạo collection mới trong một dòng dễ đọc:

numbers = [1, 2, 3, 4, 5, 6]
 
squares = [n * n for n in numbers if n % 2 == 0]   # [4, 16, 36]
lookup = {n: n * n for n in numbers}               # dict
unique_lengths = {len(w) for w in ["hi", "yo", "hey"]}  # {2, 3}

Tuy nhiên, đừng lạm dụng. Nếu comprehension lồng nhiều tầng hoặc có logic phức tạp, một vòng lặp for thông thường sẽ dễ đọc hơn.

4. Generator expression cho dữ liệu lớn

Khi chỉ cần duyệt qua một lần, thay ngoặc vuông bằng ngoặc tròn để tạo generator. Generator sinh từng phần tử khi cần thay vì tạo cả danh sách trong bộ nhớ: total = sum(x * x for x in range(1_000_000)). Đây là cách tiết kiệm bộ nhớ đáng kể khi xử lý file log hay dữ liệu lớn.

5. Tháo gỡ (unpacking) và hoán đổi biến

Python cho phép gán nhiều biến cùng lúc, kể cả hoán đổi giá trị mà không cần biến tạm:

a, b = 1, 2
a, b = b, a                 # hoán đổi
 
first, *middle, last = [10, 20, 30, 40, 50]
# first = 10, middle = [20, 30, 40], last = 50

6. Quản lý tài nguyên với with

Context manager (with) đảm bảo tài nguyên như file, kết nối, khóa được giải phóng kể cả khi có ngoại lệ:

with open("data.txt", encoding="utf-8") as f:
    for line in f:
        print(line.strip())
# File tự động đóng khi ra khỏi khối with

Lưu ý luôn chỉ định encoding="utf-8" khi làm việc với tiếng Việt để tránh lỗi trên các hệ điều hành có encoding mặc định khác.

7. Dùng dict.get, setdefault và các collection chuyên dụng

Thay vì kiểm tra if key in d rồi mới truy cập, hãy dùng d.get(key, default). Module collections còn có những công cụ rất tiện:

  • Counter để đếm tần suất: Counter("banana").most_common(1).
  • defaultdict để nhóm dữ liệu mà không cần khởi tạo khóa thủ công.
  • deque cho hàng đợi hai đầu, thêm và lấy ở hai đầu với chi phí O(1).

8. Kiểm tra giá trị "truthy" một cách tự nhiên

Trong Python, chuỗi rỗng, danh sách rỗng, 0 và None đều được coi là "falsy". Vì vậy, viết if items: thay cho if len(items) > 0:. Riêng khi so sánh với None, hãy dùng is None hoặc is not None như khuyến nghị của PEP 8, vì == có thể bị ghi đè bởi lớp tùy chỉnh.

9. EAFP: thử trước, xin lỗi sau

Python ưa chuộng phong cách EAFP (Easier to Ask Forgiveness than Permission): cứ thực hiện thao tác và bắt ngoại lệ cụ thể nếu có, thay vì kiểm tra trước mọi điều kiện.

try:
    port = int(config["port"])
except KeyError:
    port = 8080
except ValueError:
    raise ValueError("Cấu hình port không hợp lệ")

Hãy bắt ngoại lệ cụ thể, tránh except: trống vì nó nuốt mọi lỗi, kể cả lỗi bạn không lường trước.

10. f-string, dataclass và type hints

Một vài tính năng hiện đại giúp code rõ ràng hơn:

  • f-string: f"Xin chào {name}, bạn có {count} tin nhắn" dễ đọc hơn % hay .format(). Bạn còn có thể viết f"{value=}" để in nhanh cả tên biến và giá trị khi debug.
  • dataclass: thêm decorator @dataclass cho lớp chỉ chứa dữ liệu, Python tự sinh __init__, __repr__ và __eq__.
  • Type hints: chú thích kiểu như def greet(name: str) -> str: giúp IDE gợi ý tốt hơn và các công cụ như mypy phát hiện lỗi sớm.

Đừng quên PEP 8 và công cụ tự động

Pythonic không chỉ là cú pháp mà còn là sự nhất quán. PEP 8 là hướng dẫn phong cách chính thức: đặt tên hàm, biến theo snake_case, tên lớp theo CapWords, thụt lề 4 dấu cách. Thay vì nhớ hết, hãy dùng công cụ format và lint tự động như Black hoặc Ruff, tích hợp vào editor và CI để cả team viết code cùng một phong cách.

Kết luận

Viết code Pythonic là viết code mà người khác đọc vào thấy tự nhiên và dễ hiểu. Hãy bắt đầu từ những thói quen nhỏ: lặp trực tiếp, dùng comprehension hợp lý, quản lý tài nguyên bằng with, bắt ngoại lệ cụ thể. Như Zen of Python nhắc nhở, khả năng đọc hiểu (readability) luôn quan trọng. Khi phân vân, hãy chọn cách rõ ràng nhất.

Nguồn tham khảo