Ngôn ngữ lập trình Python mang lại rất nhiều điều tuyệt vời. Dù bạn là người mới bắt đầu lập trình hay chỉ mới làm quen với Python, bạn sẽ thấy ngôn ngữ này có nhiều tính năng giúp việc viết code trở nên tự nhiên và hiệu quả. Hãy cùng khám phá cách Python cung cấp những phương thức thanh lịch, dễ đọc để xử lý các tác vụ lập trình.
“Pythonic” nghĩa là gì?
Mỗi ngôn ngữ lập trình đều có những đặc điểm và quy ước riêng – những cách làm mọi thứ mà cảm thấy tự nhiên trong ngôn ngữ đó. Trong Python, có một phong cách và triết lý đặc biệt khuyến khích viết code sạch, dễ đọc và thanh lịch. Khi các nhà phát triển nói code là “Pythonic”, họ muốn nói rằng code đó tuân theo các nguyên tắc này và tận dụng tối đa những gì Python mang lại.
Thay vì chỉ viết code hoạt động được, Python khuyến khích bạn viết code còn “đẹp”. Code dễ hiểu ngay từ cái nhìn đầu tiên, ngay cả đối với người chưa từng viết nó. Code không Pythonic thường trông như được viết bằng một ngôn ngữ khác rồi dịch sang Python. Ngược lại, code Pythonic tận dụng điểm mạnh của Python, bao gồm cú pháp dễ đọc, các hàm built-in mạnh mẽ và những dòng code ngắn gọn nhưng giàu biểu cảm.
Bạn sẽ thường nghe các nhà phát triển Python nhắc đến “Zen of Python”. Đó là một tập hợp các nguyên tắc hướng dẫn ảnh hưởng đến cách viết code Python. Nó cũng được tích hợp sẵn như một Easter egg thú vị trong ngôn ngữ.
Tại sao nên viết Code theo phong cách “Pythonic”?
Vậy bạn đã biết code Pythonic là gì. Nhưng tại sao phải cố gắng viết code theo cách đó? Câu trả lời rất đơn giản: bởi vì nó làm cho cuộc sống của bạn dễ dàng hơn. Viết code Pythonic không chỉ là tuân theo một số quy tắc phong cách bất thành văn hay thể hiện các mẹo thông minh. Đó là về việc làm cho code của bạn dễ đọc hơn, dễ bảo trì hơn và thường là hiệu quả hơn.
Python được trang bị rất nhiều tính năng được thiết kế để giảm bớt boilerplate (code rập khuôn, lặp đi lặp lại) và các mẫu code nhàm chán. Một khi bạn nắm vững các idioms thông dụng, bạn sẽ thấy mình viết ít code hơn để làm được nhiều việc hơn. Học cách viết code Pythonic giúp bạn “tư duy theo kiểu Python”. Bạn sẽ bắt đầu nhận ra các mẫu code và sử dụng thư viện chuẩn hiệu quả hơn. Hơn nữa, bạn sẽ cảm thấy thoải mái hơn khi làm việc với code Python của người khác.
6 Ví dụ điển hình về Code Pythonic
Hãy cùng đi sâu vào một số ví dụ thú vị về code Pythonic sẽ thay đổi cách bạn lập trình với Python.
Đảo ngược chuỗi
Bắt đầu với một bài toán cổ điển: đảo ngược một chuỗi. Trong nhiều ngôn ngữ, bạn sẽ viết một vòng lặp để duyệt qua từng ký tự nhằm xây dựng chuỗi đã đảo ngược.
input_string = 'hello'
reversed_string = ''
for char in input_string:
reversed_string = char + reversed_string
print(reversed_string)
Cách này hoạt động tốt. Mỗi ký tự được thêm vào phía trước để tạo chuỗi đảo ngược. Nhưng nó hơi cồng kềnh. Đây là phiên bản Pythonic:
reversed_string = input_string[::-1]
Chỉ một dòng duy nhất. Cách này sử dụng cú pháp slice của Python. [::-1]
có nghĩa là “lấy toàn bộ chuỗi nhưng bước ngược lại”.
Kiểm tra sự tồn tại của phần tử trong list/tuple
Giả sử bạn muốn kiểm tra xem một mục cụ thể có tồn tại trong một list hay không. Trong nhiều ngôn ngữ, điều này thường có nghĩa là viết một vòng lặp và một số câu lệnh điều kiện.
fruits = ['strawberry', 'orange', 'apple', 'mango']
found = False
for fruit in fruits:
if fruit == 'apple':
found = True
break
print(found)
Khá nhiều code chỉ để tìm xem “apple” có trong list không. Đây là cách thực hiện trong Python:
found = 'apple' in fruits
Dòng code ngắn gọn này đọc gần giống như tiếng Anh thông thường. Nó loại bỏ nhu cầu sử dụng các biến cờ thủ công và giảm khả năng đưa lỗi vào code của bạn.
Kiểm tra nhiều điều kiện với hàm any() và all()
Đôi khi bạn muốn kiểm tra xem bất kỳ hoặc tất cả các mục trong một list có đáp ứng một điều kiện nhất định hay không. Trong nhiều ngôn ngữ, bạn sẽ sử dụng một vòng lặp với các biến cờ (flags) hoặc bộ đếm (counters) để làm điều này.
has_negative = False
for num in numbers:
if num < 0:
has_negative = True
break
Cách này khá rõ ràng, nhưng nó thêm dòng code và biến phụ. Bạn có thể làm điều này với hàm any()
trong Python.
has_negative = any(num < 0 for num in numbers)
Và nếu bạn muốn đảm bảo rằng tất cả các số đều dương:
all_positive = all(num > 0 for num in numbers)
Các hàm này hoạt động bằng cách đánh giá một điều kiện trên tất cả các phần tử và dừng lại ngay khi biết được kết quả cuối cùng (lazy evaluation).
Kết hợp các chuỗi trong list với phương thức join()
Nếu bạn từng cần xây dựng một câu hoặc kết hợp các ký tự hoặc từ từ một list, phản xạ đầu tiên của bạn có thể là lặp qua chúng và thêm từng cái một theo cách thủ công, như thế này:
sentence = ''
for word in words:
sentence += word + ' '
Cách này hoạt động, nhưng nó không hiệu quả, đặc biệt với các list lớn. Sử dụng hàm join()
của Python, bạn có thể làm điều này đơn giản hơn nhiều:
sentence = ' '.join(words)
Nó sạch hơn, nhanh hơn và biểu cảm hơn. Bạn chỉ cần chỉ định ký tự phân tách (‘ ‘ trong trường hợp này) và gọi .join()
trên nó, truyền vào list các chuỗi. Hãy đảm bảo list chỉ chứa các chuỗi vì join()
sẽ không hoạt động với số hoặc các kiểu dữ liệu khác trừ khi bạn chuyển đổi chúng trước.
Đếm số lần xuất hiện của phần tử với collections.Counter
Đếm tần suất xuất hiện của mỗi mục trong list hoặc chuỗi là một tác vụ rất phổ biến. Đây là cách bạn thường tiếp cận vấn đề này trong hầu hết các ngôn ngữ: kiểm tra xem khóa có tồn tại không, sau đó tăng giá trị của nó lên:
counts = {}
for item in items:
if item in counts:
counts[item] += 1
else:
counts[item] = 1
Sử dụng module collections
, bạn có thể làm điều tương tự với ít code hơn đáng kể.
from collections import Counter
counts = Counter(items)
Chỉ một dòng duy nhất, và nó thực hiện tất cả cho bạn. Nó trả về một đối tượng giống dictionary, trong đó khóa là các mục và giá trị là số lần xuất hiện của chúng. Counter
hoạt động trên mọi iterable, không chỉ list. Bạn có thể sử dụng nó trên chuỗi, tuple hoặc thậm chí kết quả trả về từ generator.
Hoán đổi giá trị biến và giải nén Tuple/List
Trong nhiều ngôn ngữ lập trình, việc hoán đổi giá trị giữa hai biến yêu cầu một biến tạm thời.
temp = a
a = b
b = temp
Cách này không có vấn đề gì, nhưng nó là công việc thừa và cảm thấy lỗi thời trong Python. Đây là phương pháp Pythonic:
a, b = b, a
Không cần biến tạm thời. Không lộn xộn. Cách này sử dụng khái niệm gọi là giải nén tuple (tuple unpacking), và hoán đổi biến chỉ là bước khởi đầu. Bạn cũng có thể sử dụng nó để giải nén nhiều giá trị cùng lúc.
name, age, country = ['Alice', 30, 'Canada']
Không cần truy cập từng phần tử bằng chỉ mục. Cách này hoạt động với tuple, list hoặc bất kỳ iterable nào có độ dài phù hợp.
Cẩn trọng: Đừng hy sinh tính dễ đọc vì quá “Pythonic”
Mặc dù viết code Pythonic thường là dấu hiệu của lập trình sạch và thanh lịch, đôi khi nó có thể bị lạm dụng. Một số mẫu Pythonic, đặc biệt khi sử dụng quá mức hoặc trong ngữ cảnh sai, có thể làm cho code của bạn khó đọc hơn chứ không phải dễ hơn. Một trong những giá trị cốt lõi của Python là tính dễ đọc. Trên thực tế, một trong những nguyên tắc của Zen of Python nói rằng: “Readability counts.” (Tính dễ đọc rất quan trọng). Vì vậy, vâng, sử dụng các idiom Python là tốt, nhưng không phải với cái giá biến code của bạn thành một câu đố.
List comprehensions là một ví dụ điển hình. Chúng ngắn gọn, nhanh và biểu cảm. Tuy nhiên, khi bạn bắt đầu lồng nhiều comprehension vào nhau hoặc thêm quá nhiều điều kiện, chúng có thể trở nên khó theo dõi. Hãy xem một ví dụ.
filtered = []
for user in users:
if user.is_active and user.age > 18:
filtered.append(user.name)
Đây là phiên bản sử dụng list comprehension:
filtered = [user.name for user in users if user.is_active and user.age > 18]
Mặc dù list comprehension vẫn ổn trong trường hợp này, nó sẽ nhanh chóng trở nên khó đọc nếu thêm nhiều logic hơn (như vòng lặp lồng nhau hoặc nhiều điều kiện hơn nữa). Nếu comprehension của bạn dài hơn một dòng hoặc cần suy nghĩ lần thứ hai để hiểu, có lẽ tốt hơn là nên sử dụng vòng lặp thông thường.
Có rất nhiều lý do để học Python, và cách viết code thanh lịch chỉ là một trong số đó. Một khi bạn nắm vững nó, bạn có thể khám phá các mẹo khác, chẳng hạn như sử dụng nó như một máy tính hoặc để hiểu thời lượng pin điện thoại di động của bạn.
Tài liệu tham khảo
- Zen of Python