Danh sách phụ âm python

Nhiều năm về trước, khi tôi còn là một thành viên lập trình. NET & Oracle DBA, làm một phần công việc nên thỉnh thoảng cũng có lúc sử dụng Python để viết một số tập lệnh chạy trên máy chủ hoặc thu thập dữ liệu từ các máy chủ khác. Lúc đó, tôi chỉ học các cú pháp và thực hiện một số ví dụ cơ bản bằng ngôn ngữ Python (tất nhiên là không điền vào CV là thành thạo Python rồi)

Đến một ngày, khi "học thử" buổi 01 lớp học ngoại tuyến của nhóm pymi. vn (cộng đồng người học và lập trình Python khá lớn ở Hà Nội & TP HCM), tôi thực sự bất ngờ và mê mẩn trước một "vũ khí" đặc biệt được cố vấn thực hiện demo với lớp, một cú pháp mà chỉ ngôn ngữ . hiểu danh sách. Cú pháp list-comprehension cho phép lập trình viên có thể Rút gọn các dòng mã của mình khi xử lý dữ liệu trong các mảng/mảng/danh sách xuống rất nhiều, thậm chí chỉ còn 01 dòng (so với 3-5 dòng mã thông tin)

Danh-hiểu là cái gì ?

Danh sách hiểu là một cú pháp cho phép lập trình viên nhanh chóng tạo ra một biến danh sách dữ liệu mới từ một danh sách cũ hoặc dạng vòng lặp nội tuyến, kết hợp với các điều kiện trước đó.
Về bản chất, lập trình viên hoàn toàn có thể tạo ra một danh sách mới bằng cách sử dụng vòng lặp cho/trong khi thông thường.

Cú pháp cơ bản

# basic looping 
for item in iterable:
    expression

# list comprehension
[expression for item in iterable]


Ví dụ. Create a list list of numbers from 0 to 99

# basic looping 
my_list = []
for number in range(100):
    my_list.append(number)

# list comprehension
my_comprehension_list = [number for number in range(100)]


Ví dụ. Chọn một danh sách bao gồm các số nguyên, hãy tạo một danh sách mới với các phần tử là bình phương của phần tử trong danh sách cũ

old_list = [1, 2, 3, 4, 5]

# basic looping 
new_list_1 = []
for number in old_list:
    new_list_1.append(number * number)

# list comprehension
new_list_2 = [number * number for number in old_list]

Ví dụ. Cho một danh sách bao gồm các chuỗi khác nhau, tạo ra một danh sách mới với các chuỗi ở định dạng UPPER (viết hoa)

pets = ['dog', 'cat', 'bird', 'fish', 'mouse']

# basic looping 
new_pets_1 = []
for pet in pets:
    new_pets_1.append(pet.upper())

# list comprehension
new_pets_2 = [pet.upper() for pet in pets]


Nhìn qua thì thấy hơi. khó hiểu đúng không ?

Một vài ứng dụng của việc hiểu danh sách

1. Lọc dữ liệu trong danh sách (Filter)

# basic looping with a conditional statement
for item in iterable:
    if some_condition:
        expression



# list comprehension with a conditional statement
[expression for item in iterable if some_condition]


Ví dụ. Cho một danh sách các số nguyên, tạo ra một danh sách mới chỉ chứa các số chia hết cho 3

old_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
# basic looping 

new_list_1 = []
for number in old_list:
    if number % 3 == 0:
        new_list_1.append(number)

# list comprehension
new_list_2 = [number for number in old_list if number % 3 == 0]

Ngoài cách đặt bộ lọc ở cuối, chúng ta cũng có thể đặt bộ lọc ở phía trước

Ví dụ. Cho một danh sách các số nguyên, tạo ra một danh sách mới chỉ chứa các số chia hết cho 2

old_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]

# list comprehension
new_list = [(number if number % 2 == 0  else 0) for number in old_list]
print(new_list)

# basic looping 
my_list = []
for number in range(100):
    my_list.append(number)

# list comprehension
my_comprehension_list = [number for number in range(100)]
4

2. Lọc với biểu thức so sánh bên ngoài

Bộ lọc điều kiện ở some_condition không được phép so sánh trực tiếp mà có gọi đến một chức năng bên ngoài và trả về kết quả so sánh

Ví dụ. Cho danh sách tên các con vật, tạo ra một danh sách mới chứa tên các con vật có 4 chân

________số 8

# basic looping 
my_list = []
for number in range(100):
    my_list.append(number)

# list comprehension
my_comprehension_list = [number for number in range(100)]
5

Ví dụ. Cho một danh sách các số, hãy tạo một danh sách mới là hiệu của 100 và các số trong danh sách

# basic looping 
my_list = []
for number in range(100):
    my_list.append(number)

# list comprehension
my_comprehension_list = [number for number in range(100)]
0

# basic looping 
my_list = []
for number in range(100):
    my_list.append(number)

# list comprehension
my_comprehension_list = [number for number in range(100)]
6

3. Xử lý ngoại lệ khi sử dụng tính năng hiểu danh sách

Việc gọi hàm thực hiện bộ lọc bên ngoài sẽ giúp chúng ta có thể xử lý được các ngoại lệ

Ví dụ. Thay vì tính hiệu của 100 và số trong danh sách thì yêu cầu là tính thương (chia), nếu không thực hiện xử lý ngoại lệ thì chúng ta sẽ bị lỗi khi cho phép chia cho 0

# basic looping 
my_list = []
for number in range(100):
    my_list.append(number)

# list comprehension
my_comprehension_list = [number for number in range(100)]
2

Thực hiện xử lý ngoại lệ ở hàm

# basic looping 
my_list = []
for number in range(100):
    my_list.append(number)

# list comprehension
my_comprehension_list = [number for number in range(100)]
7

# basic looping 
my_list = []
for number in range(100):
    my_list.append(number)

# list comprehension
my_comprehension_list = [number for number in range(100)]
0

# basic looping 
my_list = []
for number in range(100):
    my_list.append(number)

# list comprehension
my_comprehension_list = [number for number in range(100)]
8

4. Sử dụng kết hợp với Walrus Operator

Từ bản Python 3. 8 trở lên, Python có cú pháp khá thú vị là Walrus Operator (. = ) dùng để gán dữ liệu chung ngay trong các vòng lặp, câu lệnh so sánh,.
Việc sử dụng Walrus Operator kết hợp với danh sách hiểu để đưa ra các giải pháp khá thú vị.

Ví dụ. Cho 1 chuỗi, lấy ngẫu nhiên 10 ký tự trong chuỗi, sau đó tạo ra một danh sách, nếu các ký tự lấy ra không phải là nguyên âm thì thực hiện viết hoa ký tự đó và đưa vào danh sách

Nếu làm theo cách thông thường, hãy bỏ khoảng thời gian giới hạn dòng mã này để thực hiện

# basic looping 
my_list = []
for number in range(100):
    my_list.append(number)

# list comprehension
my_comprehension_list = [number for number in range(100)]
1

# basic looping 
my_list = []
for number in range(100):
    my_list.append(number)

# list comprehension
my_comprehension_list = [number for number in range(100)]
9

Nếu sử dụng Walrus Operator kết hợp việc hiểu danh sách

# basic looping 
my_list = []
for number in range(100):
    my_list.append(number)

# list comprehension
my_comprehension_list = [number for number in range(100)]
2

old_list = [1, 2, 3, 4, 5]

# basic looping 
new_list_1 = []
for number in old_list:
    new_list_1.append(number * number)

# list comprehension
new_list_2 = [number * number for number in old_list]
0

So sánh tốc độ xử lý hiểu danh sách và vòng lặp thông thường

Sau một vài ví dụ ở trên, chúng ta có thể thấy cách hiểu danh sách được sử dụng với 2 mục tiêu chính.
- Tạo danh sách mới từ vòng lặp.
- Thực hiện bộ lọc dữ liệu trong danh sách để tạo danh sách mới.

Bài kiểm tra này sẽ thực hiện kiểm tra tốc độ xử lý của 2 trường hợp trên

# basic looping 
my_list = []
for number in range(100):
    my_list.append(number)

# list comprehension
my_comprehension_list = [number for number in range(100)]
3

Thời gian chạy lần 1.

old_list = [1, 2, 3, 4, 5]

# basic looping 
new_list_1 = []
for number in old_list:
    new_list_1.append(number * number)

# list comprehension
new_list_2 = [number * number for number in old_list]
1
old_list = [1, 2, 3, 4, 5]

# basic looping 
new_list_1 = []
for number in old_list:
    new_list_1.append(number * number)

# list comprehension
new_list_2 = [number * number for number in old_list]
2
old_list = [1, 2, 3, 4, 5]

# basic looping 
new_list_1 = []
for number in old_list:
    new_list_1.append(number * number)

# list comprehension
new_list_2 = [number * number for number in old_list]
3
old_list = [1, 2, 3, 4, 5]

# basic looping 
new_list_1 = []
for number in old_list:
    new_list_1.append(number * number)

# list comprehension
new_list_2 = [number * number for number in old_list]
4

Thời gian chạy lần 2.
______25

old_list = [1, 2, 3, 4, 5]

# basic looping 
new_list_1 = []
for number in old_list:
    new_list_1.append(number * number)

# list comprehension
new_list_2 = [number * number for number in old_list]
6
old_list = [1, 2, 3, 4, 5]

# basic looping 
new_list_1 = []
for number in old_list:
    new_list_1.append(number * number)

# list comprehension
new_list_2 = [number * number for number in old_list]
7
old_list = [1, 2, 3, 4, 5]

# basic looping 
new_list_1 = []
for number in old_list:
    new_list_1.append(number * number)

# list comprehension
new_list_2 = [number * number for number in old_list]
8

Thời gian chạy lần 3.
______29

pets = ['dog', 'cat', 'bird', 'fish', 'mouse']

# basic looping 
new_pets_1 = []
for pet in pets:
    new_pets_1.append(pet.upper())

# list comprehension
new_pets_2 = [pet.upper() for pet in pets]
0
pets = ['dog', 'cat', 'bird', 'fish', 'mouse']

# basic looping 
new_pets_1 = []
for pet in pets:
    new_pets_1.append(pet.upper())

# list comprehension
new_pets_2 = [pet.upper() for pet in pets]
1
pets = ['dog', 'cat', 'bird', 'fish', 'mouse']

# basic looping 
new_pets_1 = []
for pet in pets:
    new_pets_1.append(pet.upper())

# list comprehension
new_pets_2 = [pet.upper() for pet in pets]
2

Nhìn vào kết quả trên, chúng ta đã thấy list-comprehension đang nhanh hơn cách làm thông thường, vậy có lý do gì mà trình lập trình Python lại không sử dụng list-comprehension nhỉ?