Menu

List comprehension trong Python: cú pháp, lọc, dict comprehension

List comprehension giúp bạn tạo một list mới trên một dòng dễ đọc, để biến đổi, lọc hoặc cả hai, thay cho kiểu viết vòng lặp rồi append.

Trang này có trình soạn thảo chạy trực tiếp. Sửa, chạy và xem đầu ra ngay lập tức.

Một dòng, một ý

Bạn đã viết kiểu code này nhiều lần: bắt đầu với một list rỗng, lặp qua thứ gì đó, có thể lọc bớt, rồi append vào kết quả.

List comprehension nói đúng điều đó trên một dòng:

Đọc từ trái sang phải: "một list mới gồm n * 2, với mỗi n trong numbers." Cấu trúc là [expression for item in iterable].

Đây không phải mẹo riêng của Python. Nó được gọi là comprehension vì bạn mô tả những gì có trong list mới theo kiểu khai báo, thay vì viết ra từng bước cách tạo nó.

Thêm điều kiện lọc

Đặt một mệnh đề if sau phần vòng lặp để lọc:

Đọc ví dụ thứ hai như sau: "n * n với mỗi n trong numbers, nhưng chỉ khi n là số lẻ."

Vòng lặp tương đương:

Cả hai đều ổn. Comprehension ngắn hơn, và khi đã đọc quen vài cái, bạn sẽ thấy nó còn dễ nhìn hơn vì ý định nằm gọn ngay trên một dòng.

Vừa biến đổi vừa lọc

Bạn có thể đưa giá trị qua một hàm và lọc cùng lúc:

Với mỗi từ dài hơn 3 chữ cái, lấy bản viết hoa của nó.

Vòng lặp lồng nhau trong comprehension

Hai vòng for tạo ra các cặp theo kiểu tích Descartes:

Thứ tự giống hệt như khi bạn lồng các vòng lặp: for đầu tiên là vòng ngoài, for thứ hai là vòng trong. Nó đọc từ trái sang phải giống vòng lặp thụt lề tương đương.

Hai cấp gần như là giới hạn, quá mức đó thì vòng lặp thường dễ đọc hơn. Nếu đã tới ba cấp, hãy quay lại dùng vòng lặp.

Dictionary và set comprehension

Cùng một ý tưởng, chỉ khác dấu ngoặc:

Thoạt nhìn set comprehension trông giống hệt dict comprehension. Điểm khác là key: value so với chỉ một biểu thức. Ngoặc nhọn có : là dict; ngoặc nhọn không có : là set.

Generator expression

Gần như là anh em sinh đôi của list comprehension, nhưng dùng ngoặc tròn thay cho ngoặc vuông, và quan trọng nhất là nó không tạo ra list:

Để ý rằng ta truyền generator thẳng vào sum() và any(), không cần thêm cặp ngoặc nào. Generator expression là công cụ phù hợp khi bên gọi chỉ cần lặp qua một lần. Với tập dữ liệu lớn, nó tiết kiệm bộ nhớ hơn hẳn một list đầy đủ.

Khi nào nên dùng vòng lặp thường

Comprehension rất hấp dẫn. Về mặt kỹ thuật, bạn có thể nhồi rất nhiều thứ vào một dòng. Nhưng đừng làm thế.

Hãy dùng vòng lặp thường khi:

  • Phép biến đổi có nhiều hơn một bước. Nếu cần biến trung gian, hãy viết ra đầy đủ.
  • Có xử lý lỗi hoặc rẽ nhánh phức tạp.
  • Người đọc phải dừng lại nhiều hơn một lần mới hiểu được dòng code.

Một quy tắc dễ áp dụng: nếu đọc một hơi mà hiểu ngay comprehension làm gì thì giữ lại. Nếu bị vấp, viết lại thành vòng lặp.

Có những comprehension trông thông minh nhưng lại gây khó:

Cùng một kết quả. Bản vòng lặp dài năm dòng thay vì một, nhưng "dài hơn" không có nghĩa là "tệ hơn".

Vài mẫu bạn sẽ dùng đi dùng lại

Mấy mẫu này bao quát được một lượng đáng kể công việc xử lý dữ liệu hằng ngày.

Tiếp theo

Bạn đã thấy các kiểu tập hợp chính và comprehension, thứ gắn kết chúng lại với nhau. Chương tiếp theo: hàm (function), cách đóng gói hành vi thành những đơn vị có tên và dùng lại được.

Câu hỏi thường gặp

List comprehension trong Python là gì?

Một cú pháp ngắn gọn để tạo list mới từ một iterable có sẵn. [x * 2 for x in numbers] tạo một list mới với mỗi số được nhân đôi. Bạn cũng có thể lọc: [x for x in numbers if x > 0].

Khi nào không nên dùng list comprehension?

Khi nó làm code khó đọc hơn. Nếu biểu thức bên trong phức tạp hoặc lồng nhau quá sâu, một vòng lặp for bình thường với tên biến rõ ràng sẽ dễ hiểu hơn. Comprehension dành cho những phép biến đổi đơn giản: ánh xạ và lọc. Việc gì phức tạp hơn thì nên viết thành vòng lặp đầy đủ.

List comprehension và generator expression khác nhau thế nào?

List comprehension tạo toàn bộ list trong bộ nhớ. Generator expression (cú pháp giống hệt nhưng dùng dấu ngoặc tròn) sinh ra từng phần tử một. Hãy dùng generator khi kết quả được đưa vào thứ chỉ lặp qua một lần, như sum(...), để không phải tạo ra một list rồi vứt đi ngay.

Hình minh họa các ngôn ngữ lập trình của Coddy

Học lập trình cùng Coddy

Bắt đầu