List Comprehension trong Python cho phép tạo list mới từ danh sách hiện có một cách ngắn gọn và hiệu quả. Thay vì phải sử dụng vòng lặp for truyền thống, List Comprehension cung cấp cú pháp đơn giản hơn, giúp mã nguồn dễ đọc và tối ưu hơn. Nhưng List Comprehension thực sự hoạt động như thế nào và cú pháp cụ thể của nó ra sao? Hãy cùng tìm hiểu chi tiết hơn trong bài viết dưới đây.
Các điểm chính
Khi đọc xong bài viết, bạn sẽ:
- Hiểu rõ khái niệm List Comprehension: Bạn sẽ nắm vững List Comprehension là gì, tại sao nó lại quan trọng và khác biệt so với các phương pháp khác trong Python.
- Nắm vững cú pháp và cách sử dụng: Bài viết sẽ giải thích chi tiết cú pháp của List Comprehension, giúp bạn viết code một cách chính xác và hiệu quả. Các ví dụ minh họa sẽ giúp bạn hiểu rõ hơn cách sử dụng nó trong thực tế.
- So sánh và áp dụng: Bạn sẽ hiểu cách List Comprehension liên hệ với các khái niệm khác như Lambda, vòng lặp for và điều kiện (if) trong Python. Bạn sẽ biết cách áp dụng nó vào các bài toán thực tế, từ đơn giản đến phức tạp, kể cả những trường hợp có vòng lặp lồng nhau.
- Thấy được ưu điểm: Bạn sẽ hiểu được những ưu điểm vượt trội của List Comprehension so với cách viết code thông thường, giúp bạn viết code ngắn gọn, dễ đọc và hiệu quả hơn.
List Comprehension trong Python
List Comprehension là một cách ngắn gọn để tạo List. Tương tự như ký hiệu xây dựng tập hợp (set-builder notation) trong toán học. List Comprehension được sử dụng để định nghĩa một List mới dựa trên một đối tượng có thể lặp (iterable) hiện có, chẳng hạn như List, tuple, hoặc chuỗi, và áp dụng một biểu thức cho mỗi phần tử trong đối tượng có thể lặp đó.

Cú pháp của List Comprehension
Cú pháp cơ bản của List Comprehension là:
new_list = [biểu_thức for phần_tử in đối_tượng_có_thể_lặp if điều_kiện]
Trong đó:
biểu_thức:
Là phép toán hoặc biến đổi áp dụng cho mỗiphần_tử
trongđối_tượng_có_thể_lặp
.phần_tử
: Là biến đại diện cho mỗi phần tử trongđối_tượng_có_thể_lặp
.đối_tượng_có_thể_lặp
: Là chuỗi các phần tử cần lặp qua (ví dụ: List, tuple, chuỗi…).điều_kiện
(tùy chọn): Là một biểu thức lọc các phần tử dựa trên một điều kiện cụ thể.
Ví dụ về List Comprehension trong Python
Giả sử, chúng ta muốn chuyển tất cả các chữ cái trong chuỗi “Xin chào các bạn!” thành dạng chữ in hoa. Sử dụng List Comprehension, chúng ta duyệt qua từng ký tự, kiểm tra xem ký tự đó có phải là chữ cái không, và nếu đúng, chuyển ký tự đó thành chữ in hoa. Kết quả trả về là một List các chữ cái in hoa:
chuoi = "Xin chào các bạn!"
chu_in_hoa = [ky_tu.upper() for ky_tu in chuoi if ky_tu.isalpha()]
print(chu_in_hoa)
Kết quả thu được sẽ hiển thị như sau:
[‘X’, ‘I’, ‘N’, ‘C’, ‘H’, ‘À’, ‘O’, ‘C’, ‘Á’, ‘C’, ‘B’, ‘Ạ’, ‘N’]
Giải thích code:
chuoi = "Xin chào các bạn!"
: Khai báo một biếnchuoi
kiểustring
.chu_in_hoa = [ky_tu.upper() for ky_tu in chuoi if ky_tu.isalpha()]
: Tạo ra List mới từ List Comprehension.for ky_tu in chuoi:
: Vòng lặpfor
duyệt từng ký tự trong chuỗichuoi
.if ky_tu.isalpha():
: Điều kiện kiểm tra nếu ký tự đó có phải là chữ cái thì mới đưa vào List.ky_tu.upper():
: Với mỗi ký tự thỏa điều kiện trên thì chuyển sang in hoa.
List Comprehensions và Lambda
Trong Python, lambda là một từ khóa được sử dụng để tạo các hàm ẩn danh (anonymous functions). Hàm ẩn danh là một hàm được định nghĩa mà không có tên. Các hàm này được tạo bằng cách sử dụng từ khóa lambda, theo sau là danh sách các đối số (cách nhau bởi dấu phẩy), tiếp đến là dấu hai chấm :,
và cuối cùng là biểu thức cần được tính toán.
Chúng ta có thể sử dụng list comprehension với lambda bằng cách áp dụng hàm lambda cho từng phần tử của một iterable (đối tượng có thể lặp) bên trong list comprehension, từ đó tạo ra một list mới.
Trong ví dụ sau, chúng ta sử dụng list comprehension với một hàm lambda để nhân đôi mỗi phần tử trong list cho trước là original_list
. Chúng ta lặp qua từng phần tử trong original_list
và áp dụng hàm lambda để nhân đôi giá trị của phần tử đó:
original_list = [1, 2, 3, 4, 5]
doubled_list = [(lambda x: x * 2)(x) for x in original_list]
print(doubled_list)
Kết quả đầu ra của đoạn mã trên sẽ là:
[2, 4, 6, 8, 10]
Giải thích:
original_list = [1, 2, 3, 4, 5]
: Khởi tạo một list có tên làoriginal_list
chứa các số nguyên từ 1 đến 5.doubled_list = [(lambda x: x * 2)(x) for x in original_list]
: Đây là phần chính, sử dụng list comprehension kết hợp với hàm lambda. Hãy chia nhỏ nó ra:for x in original_list
: Phần này lặp qua từng phần tử (x
) trongoriginal_list
.(lambda x: x * 2)(x)
: Đây là một hàm lambda được định nghĩa và gọi ngay lập tức.lambda x: x * 2
: Định nghĩa một hàm lambda nhận một đối sốx
và trả vềx * 2
(gấp đôix
).(x)
: Gọi ngay hàm lambda vừa định nghĩa với đối số làx
(giá trị hiện tại trong vòng lặp).- Toàn bộ biểu thức
(lambda x: x * 2)(x)
sẽ được thực hiện cho mỗix
trongoriginal_list
, và kết quả được đưa vàodoubled_list
. print(doubled_list)
: In radoubled_list
, kết quả là một list mới chứa các phần tử đã được nhân đôi.
Vòng lặp lồng nhau trong List Comprehension
Vòng lặp lồng nhau (nested loop) trong Python là một vòng lặp nằm bên trong một vòng lặp khác. Vòng lặp bên trong sẽ được thực thi nhiều lần cho mỗi lần lặp của vòng lặp bên ngoài.
Chúng ta có thể sử dụng vòng lặp lồng nhau trong List Comprehension bằng cách đặt một vòng lặp bên trong một vòng lặp khác. Cách sử dụng này cho phép tạo các List một cách ngắn gọn từ nhiều lần lặp.
Trong ví dụ này, tất cả các tổ hợp của các phần tử từ hai List dưới dạng một tuple sẽ được thêm vào một List thứ ba:
list1 = [1, 2, 3]
list2 = [4, 5, 6]
CombLst = [(x, y) for x in list1 for y in list2]
print(CombLst)
Kết quả đầu ra sẽ như sau:
[(1, 4), (1, 5), (1, 6), (2, 4), (2, 5), (2, 6), (3, 4), (3, 5), (3, 6)]
Giải thích:
list1
vàlist2
: là haiList
ban đầu.CombLst = [(x, y) for x in list1 for y in list2]
: Đây là phần chính, sử dụngList Comprehension
với vòng lặp lồng nhau:for x in list1
: Đây là vòng lặp bên ngoài, duyệt qua từng phần tửx
tronglist1
.for y in list2
: Đây là vòng lặp bên trong, ứng với mỗi giá trịx
, vòng lặp này duyệt qua từng phần tửy
tronglist2
.(x, y)
: Với mỗi cặp giá trịx
vày
, một tuple(x, y)
được tạo ra.[...]
: Tất cả các tuple(x, y)
được tạo ra sẽ được tập hợp lại thành mộtList
, vàList
này được gán cho biếnCombLst
.
Điều kiện trong Python List Comprehension
Điều kiện (Conditionals) trong Python là việc sử dụng các câu lệnh như if
, elif
, và else
để kiểm soát luồng thực thi của code dựa trên các điều kiện cụ thể. Chúng cho phép bạn thực hiện các khối code khác nhau tùy thuộc vào việc một điều kiện được đánh giá là True hay False.
Chúng ta có thể áp dụng các điều kiện trong List Comprehension bằng cách thêm chúng vào sau phần iterable (đối tượng có thể lặp, ví dụ như List, range,…) và trước vòng lặp. Các điều kiện này có tác dụng lọc các phần tử từ iterable, dựa trên điều kiện được chỉ định, trong khi List mới được tạo ra.
Đoạn code sau đây sử dụng điều kiện trong List Comprehension để tạo một List chứa các số chẵn từ 1 đến 20:
list1 = [x for x in range(1, 21) if x % 2 == 0]
print(list1)
Kết quả chúng ta nhận được sẽ là:
[2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
Giải thích chi tiết:
[x for x in range(1, 21) if x % 2 == 0]
: Đây là một List Comprehension.x for x in range(1, 21)
: Phần này tương tự như một vòng lặpfor
thông thường.range(1, 21)
tạo ra một chuỗi các số từ 1 đến 20 (không bao gồm 21). Biếnx
sẽ lần lượt nhận các giá trị trong chuỗi số này.if x % 2 == 0
: Đây là phần điều kiện. Toán tử%
là toán tử chia lấy phần dư. Biểu thứcx % 2 == 0
kiểm tra xemx
có chia hết cho 2 hay không (phần dư có bằng 0 hay không). Nếux
là số chẵn (chia hết cho 2), điều kiện này trả vềTrue
.- Giá trị của
x
chỉ được thêm vàoList
mới (list1
) nếu điều kiệnif
làTrue
. print(list1)
: In danh sáchlist1
chứa các số chẵn đó ra màn hình.
List Comprehensions và vòng lặp for
List comprehensions và vòng lặp for
đều được sử dụng để lặp, nhưng chúng khác nhau về cú pháp và cách sử dụng.
List comprehensions giống như những “lối tắt” để tạo List (danh sách) trong Python. Chúng cho phép bạn tạo một List mới bằng cách áp dụng một phép toán lên từng phần tử trong một List đã có.
Mặt khác, vòng lặp for
là một câu lệnh điều khiển luồng, được sử dụng để duyệt qua từng phần tử của một đối tượng có thể lặp (iterable), thực hiện một khối code cho mỗi phần tử.
List comprehensions thường được ưu tiên cho các thao tác đơn giản, trong khi vòng lặp for
mang lại sự linh hoạt hơn cho các công việc phức tạp.
Ví dụ sử dụng vòng lặp for
Giả sử chúng ta muốn tách từng chữ cái trong một chuỗi và đưa tất cả các chữ cái không phải là nguyên âm vào một List. Chúng ta có thể thực hiện việc này bằng một vòng lặp for
như sau:
chuoi = 'Chao mung den voi Python'
ket_qua = []
for ky_tu in chuoi:
if ky_tu not in 'ueoai': #kiểm tra phụ âm
ket_qua.append(ky_tu)
print(ket_qua)
Kết quả của ket_qua sẽ là:
[‘C’, ‘h’, ‘ ‘, ‘m’, ‘n’, ‘g’, ‘ ‘, ‘d’, ‘n’, ‘ ‘, ‘v’, ‘i’, ‘ ‘, ‘P’, ‘y’, ‘t’, ‘h’, ‘n’]
Giải thích:
chuoi = 'Chao mung den voi Python'
: Đầu tiên, ta có một chuỗi (string
)chuoi
được khởi tạo với một câu tiếng Việt.ket_qua = []
: MộtList
rỗng có tên làket_qua
được tạo ra.List
này sẽ dùng để chứa các chữ cái sau khi được lọc.for ky_tu in chuoi:
: Đây là vòng lặpfor
. Biếnky_tu
sẽ lần lượt nhận giá trị là từng ký tự trong chuỗichuoi
trong mỗi lần lặp.if ky_tu not in 'ueoai':
: Trong mỗi lần lặp, câu lệnhif
này sẽ kiểm tra xem ký tự hiện tại (ky_tu
) có phải là một trong các nguyên âm ('u'
,'e'
,'o'
,'a'
,'i'
) hay không. Lưu ý'ueoai'
trong tiếng Việt.ket_qua.append(ky_tu)
: Nếuky_tu
không phải là nguyên âm (tức là điều kiệnif
đúng), ký tự đó sẽ được thêm vào cuốiList
ket_qua
bằng phương thứcappend()
.print(ket_qua)
: Sau khi vòng lặp chạy xong, danh sách các ký tự đã lọc được in ra màn hình.
Ví dụ sử dụng List Comprehension
Chúng ta có thể dễ dàng đạt được kết quả tương tự bằng kỹ thuật List Comprehension. Cách sử dụng chung của List Comprehension như sau:
danh_sach_moi = [bieu_thuc for phan_tu in doi_tuong_lap]
Giải thích cú pháp:
danh_sach_moi
: Đây làList
mới sẽ được tạo ra.bieu_thuc
: Đây là một biểu thứcPython
. Biểu thức này thường sử dụngphan_tu
và giá trị của biểu thức này sẽ trở thành một phần tử trongdanh_sach_moi
.phan_tu
: Đây là một biến, nó lần lượt đại diện cho từng giá trị trongdoi_tuong_lap
.for phan_tu in doi_tuong_lap
: Vòng lặpfor
này duyệt qua từng phần tử trongdoi_tuong_lap
(một đối tượng có thể lặp, như một chuỗi,List
, …).
Áp dụng điều này, List chars (ở ví dụ vòng lặp for
trước đó) có thể được xây dựng bằng câu lệnh sau:
chuoi = 'Chao mung den voi Python'
ket_qua = [ky_tu for ky_tu in chuoi if ky_tu not in 'ueoai']
print(ket_qua)
Kết quả hiển thị của ket_qua sẽ giống như trước:
[‘C’, ‘h’, ‘ ‘, ‘m’, ‘n’, ‘g’, ‘ ‘, ‘d’, ‘n’, ‘ ‘, ‘v’, ‘i’, ‘ ‘, ‘P’, ‘y’, ‘t’, ‘h’, ‘n’]
Ví dụ khác
Ví dụ sau sử dụng List Comprehension để tạo một List chứa bình phương của các số từ 1 đến 10:
binh_phuong = [x * x for x in range(1, 11)]
print(binh_phuong)
Kết quả là:
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
Giải thích code:
[x * x for x in range(1, 11)]
: Đây là một List Comprehension.for x in range(1, 11):
: Vòng lặpfor
duyệt qua các số từ 1 đến 10 (hàmrange(1, 11)
tạo ra một dãy số từ 1 đến 10).x * x
: Với mỗi giá trịx
, biểu thứcx * x
(bình phương củax
) sẽ được tính toán, và kết quả được thêm vào Listbinh_phuong
.
Ưu điểm của List Comprehension trong Python
Dưới đây là những ưu điểm khi sử dụng List Comprehension:
- Tính súc tích: List Comprehension ngắn gọn và dễ đọc hơn so với vòng lặp for truyền thống, cho phép bạn tạo List với ít code hơn.
- Hiệu quả: List Comprehension thường nhanh và hiệu quả hơn vòng lặp for vì List Comprehension được trình thông dịch của Python tối ưu hóa bên trong.
- Rõ ràng: List Comprehension giúp code rõ ràng và biểu cảm hơn, làm cho việc hiểu mục đích và logic của thao tác đang thực hiện trở nên dễ dàng.
- Giảm thiểu khả năng lỗi: Vì List Comprehension nhỏ gọn hơn, nên ít có khả năng xảy ra lỗi hơn so với các vòng lặp for truyền thống, giảm thiểu nguy cơ bug (lỗi) trong code của bạn.
Lời kết
Như vậy, chúng ta đã cùng nhau tìm hiểu chi tiết về List Comprehension trong Python, từ cú pháp, cách sử dụng, cho đến các ví dụ minh họa cụ thể. List Comprehension không chỉ giúp code của bạn trở nên gọn gàng, dễ đọc hơn mà còn tối ưu hiệu suất đáng kể. Hy vọng rằng, với những kiến thức này, bạn có thể áp dụng List Comprehension một cách hiệu quả vào các dự án Python của mình.
Mọi người cũng đọc