Giới thiệu
Trong bài viết trước, chúng ta đã sử dụng filter() để trích xuất các số chẵn từ một danh sách. Mặc dù cách đó hiệu quả, nhưng nó yêu cầu sử dụng lambda và bọc kết quả trong list(). Có một cách diễn đạt hơn, đúng với phong cách Python hơn để thực hiện điều này: list comprehension.
List comprehension là một cách ngắn gọn và dễ đọc để tạo ra một danh sách mới bằng cách xử lý hoặc lọc các mục trong một iterable hiện có. Hãy nghĩ về nó như một dây chuyền lắp ráp tinh gọn cho dữ liệu của bạn: các mục được đưa vào, có thể được kiểm tra, biến đổi và đóng gói vào một danh sách mới—tất cả đều trong một dòng mã hiệu quả.
Mô hình cơ bản: Biến đổi dữ liệu
Hãy bắt đầu với phương pháp vòng lặp cổ điển để tạo ra một danh sách mới và xem cách mà comprehension đơn giản hóa nó.
Cách "Dài" (sử dụng vòng lặp for):
python
numbers = [1, 2, 3, 4, 5]
squares = []
for num in numbers:
squares.append(num ** 2)
print(squares) # Kết quả: [1, 4, 9, 16, 25]
Cách Pythonic (sử dụng list comprehension):
python
numbers = [1, 2, 3, 4, 5]
squares = [num ** 2 for num in numbers] # Biến đổi từng phần tử
print(squares) # Kết quả: [1, 4, 9, 16, 25]
Cấu trúc rất đơn giản: [new_value for item in iterable]. Nó đọc gần như tiếng Anh: "Cho tôi một danh sách của 'num bình phương' cho mỗi 'num' trong 'numbers'." Không chỉ dễ đọc hơn, mà nó còn thường nhanh hơn so với việc xây dựng một danh sách bằng vòng lặp, đặc biệt là đối với các tập dữ liệu lớn.
Cấp độ 2: Thêm lọc với if
Nếu bạn chỉ muốn biến đổi một số mục? Đây là nơi mà list comprehensions thực sự tỏa sáng, thay thế nhu cầu sử dụng filter() trong nhiều trường hợp.
Nhớ lại ví dụ filter() cho các số chẵn:
python
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9]
evens = list(filter(lambda x: x % 2 == 0, numbers))
Dưới đây là phương pháp rõ ràng hơn, dựa trên comprehension:
python
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9]
evens = [num for num in numbers if num % 2 == 0] # Lọc và bao gồm
print(evens) # Kết quả: [2, 4, 6, 8]
Cấu trúc bây giờ là: [item for item in iterable if condition]. Nó đọc: "Cho tôi một danh sách của 'num' cho mỗi 'num' trong 'numbers' nếu số đó là chẵn." Không cần lambda!
Cấp độ 3: Biến đổi dữ liệu đã lọc
Bạn có thể kết hợp cả biến đổi và lọc trong một dòng mạnh mẽ duy nhất. Thứ tự thực hiện rất quan trọng: [<what to output> for <item> in <iterable> if <condition>]. <condition> hoạt động như một bộ lọc, và <what to output> biến đổi các mục vượt qua điều kiện đó.
Nhiệm vụ: Lấy bình phương của tất cả các số chẵn.
python
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9]
squares_of_evens = [num ** 2 for num in numbers if num % 2 == 0]
print(squares_of_evens) # Kết quả: [4, 16, 36, 64]
Điều này ngắn gọn và dễ đọc hơn nhiều so với việc viết một vòng lặp kiểm tra điều kiện và sau đó thêm một giá trị đã biến đổi.
Ngoài danh sách: Sức mạnh của comprehension
Mô hình comprehension được yêu thích đến mức nó đã được mở rộng sang các cấu trúc dữ liệu khác, thúc đẩy sự nhất quán trong toàn bộ ngôn ngữ.
Dictionary Comprehension:
python
# Tạo một từ điển ánh xạ số với bình phương của chúng
numbers = [1, 2, 3, 4]
squares_dict = {num: num**2 for num in numbers}
print(squares_dict) # Kết quả: {1: 1, 2: 4, 3: 9, 4: 16}
Set Comprehension:
python
# Tạo một tập hợp các bình phương duy nhất (các phần tử trùng lặp sẽ tự động bị loại bỏ)
numbers = [1, 2, 2, 3, 4]
unique_squares = {num**2 for num in numbers}
print(unique_squares) # Kết quả: {1, 4, 9, 16}
Khi nào nên giữ lại vòng lặp
List comprehensions rất tuyệt vời, nhưng chúng không phải lúc nào cũng là câu trả lời. Ưu tiên tính dễ đọc.
- Sử dụng comprehension cho việc biến đổi và/hoặc lọc đơn giản. Chúng rất hoàn hảo cho các tác vụ này.
- Sử dụng vòng lặp for truyền thống khi logic phức tạp, bạn cần nhiều điều kiện hoặc bạn cần sử dụng các câu lệnh như
print()hoặcbreaktrong vòng lặp.
Siêu năng lực mới của bạn
Bây giờ bạn đã có một công cụ mạnh mẽ để viết mã thanh lịch, hiệu quả và đúng phong cách Python. List comprehension là một dấu hiệu của một lập trình viên Python có kinh nghiệm. Hãy nhớ cú pháp đơn giản của nó:
- Biến đổi:
[<expression> for <item> in <iterable>] - Lọc:
[<item> for <item> in <iterable> if <condition>] - Biến đổi & Lọc:
[<expression> for <item> in <iterable> if <condition>]
Sử dụng chúng để làm cho mã của bạn sạch hơn, nhanh hơn và dễ đọc hơn.
Kết luận
Chúng ta đã làm chủ việc tạo ra và lọc dữ liệu. Bây giờ hãy cùng khám phá cách điều hướng nó một cách dễ dàng thông qua việc tìm hiểu về Cắt và Đánh chỉ số trong Python để truy cập bất kỳ phần nào của danh sách và chuỗi của bạn với độ chính xác.
Câu hỏi thường gặp
List comprehension là gì?
List comprehension là một cách ngắn gọn và dễ hiểu để tạo danh sách mới bằng cách xử lý các phần tử từ danh sách hoặc iterable khác.
Khi nào nên sử dụng list comprehension thay cho vòng lặp?
Sử dụng list comprehension khi bạn cần biến đổi hoặc lọc dữ liệu một cách đơn giản. Nếu logic phức tạp, nên sử dụng vòng lặp truyền thống.
Có thể sử dụng list comprehension cho các cấu trúc dữ liệu khác không?
Có, list comprehension có thể được mở rộng cho dictionary và set, giúp tạo ra các cấu trúc dữ liệu khác một cách nhanh chóng và hiệu quả.
Tài nguyên tham khảo
Hãy bắt đầu sử dụng list comprehension để nâng cao kỹ năng lập trình Python của bạn!