Một trong những tình huống mà lập trình phát huy tác dụng mạnh nhất là xử lý chuỗi các mục và sự kiện. Máy tính rất giỏi trong việc lặp lại mọi thứ. Ví dụ, trong các phần trước của tài liệu này, chúng ta đã lặp lại các chuỗi, danh sách và từ điển theo nhiều cách khác nhau
Giả sử chúng ta có một danh sách các số nguyên và chúng ta sẽ cần cùng một danh sách các mục ở định dạng chuỗi. Một cách truyền thống để hoàn thành nhiệm vụ có thể trông như thế này
numbers = [1, 2, 3, 6, 5, 4, 7]
strings = []
for number in numbers:
strings.append[str[number]]
Danh sách hiểu
Ngoài ra còn có một cách "pythonic" hơn để tạo danh sách từ danh sách hiện có. Chúng được gọi là hiểu danh sách
Ý tưởng là để phù hợp trên một dòng duy nhất cả mô tả về những gì nên được thực hiện cho từng mục trong danh sách và việc gán kết quả cho một danh sách mới
Trong ví dụ trên, thao tác được thực hiện trên từng mục trong danh sách rất đơn giản. mỗi số nguyên đã được chuyển đổi thành một chuỗi. Hãy xem điều này sẽ trông như thế nào khi được triển khai với khả năng hiểu danh sách
numbers = [1, 2, 3, 6, 5, 4, 7]
strings = [str[number] for number in numbers]
Dòng thứ hai ở trên chứa nhiều phần tử giống như cách tiếp cận lặp truyền thống hơn, nhưng cú pháp thì khác. Một cách để khái quát hóa một tuyên bố hiểu danh sách sẽ là
numbers = [1, 2, 3, 6, 5, 4, 7]
strings = [str[number] for number in numbers]
3Các dấu ngoặc vuông xung quanh câu lệnh hiểu danh sách báo hiệu cho Python rằng kết quả phải là một danh sách mới. Từng mục một, từng mục trong danh sách ban đầu được xử lý và kết quả được lưu trữ trong danh sách mới, giống như trong phương pháp lặp ở trên. Kết quả là chúng tôi có một danh sách mới với số mục chính xác như trong danh sách ban đầu và tất cả các mục đã được xử lý theo cách giống hệt nhau
[NB. bản gốc của các hình ảnh trong phần này tạm thời bị thiếu, đó là lý do tại sao có một số từ vựng tiếng Phần Lan trong hình minh họa của phần này. Chúng tôi đang tiếp tục sửa chữa. ]
Khả năng hiểu danh sách cũng có thể xử lý các hoạt động phức tạp hơn nhiều. Chúng ta có thể thực hiện các phép tính, chẳng hạn như nhân các mục ban đầu với mười
numbers = list[range[1,10]]
print[numbers]
numbers_multiplied = [number * 10 for number in numbers]
print[numbers_multiplied]
đầu ra mẫu
[1, 2, 3, 4, 5, 6, 7, 8, 9] [10, 20, 30, 40, 50, 60, 70, 80, 90]
Trên thực tế, biểu thức trong câu lệnh hiểu danh sách có thể là bất kỳ biểu thức Python nào. Bạn thậm chí có thể gọi các chức năng mà bạn đã tự xác định
def factorial[n: int]:
""" The function calculates the factorial n! for integers above zero """
k = 1
while n >= 2:
k *= n
n -= 1
return k
if __name__ == "__main__":
numbers = [5, 2, 4, 3, 0]
factorials = [factorial[number] for number in numbers]
print[factorials]
đầu ra mẫu
[120, 2, 24, 6, 1]
Với vòng lặp
numbers = [1, 2, 3, 6, 5, 4, 7]
strings = [str[number] for number in numbers]
4 quen thuộc hơn, quy trình tương tự có thể được diễn đạt như saudef factorial[n: int]:
""" The function calculates the factorial n! for integers above zero """
k = 1
while n >= 2:
k *= n
n -= 1
return k
if __name__ == "__main__":
numbers = [5, 2, 4, 3, 0]
factorials = []
for number in numbers:
factorials.append[factorial[number]]
print[factorials]
Khả năng hiểu danh sách cho phép chúng tôi diễn đạt chức năng tương tự một cách dễ hiểu hơn, thường là không làm mất bất kỳ khả năng đọc nào
Chúng ta cũng có thể trực tiếp trả về một câu lệnh hiểu danh sách từ một hàm. Nếu chúng ta cần một hàm để tạo giai thừa cho danh sách các số, chúng ta có thể đạt được nó rất ngắn gọn
def factorials[numbers: list]:
return [factorial[number] for number in numbers]
Đang tải
Đang tải
Đang tải
Đang tải
Lọc các mục
Trong các ví dụ trên, tất cả các danh sách của chúng ta đều giữ nguyên độ dài trước và sau thao tác hiểu danh sách. Trong mỗi trường hợp, tất cả các mục trong danh sách ban đầu được sử dụng làm cơ sở cho danh sách mới. Nhưng đôi khi chúng ta chỉ cần một số mặt hàng ban đầu. Làm thế nào điều này có thể đạt được?
Một câu lệnh hiểu danh sách cũng cho phép một điều kiện, để chúng ta có thể kiểm tra các mục theo điều kiện và chỉ chọn những mục phù hợp. Cú pháp chung như sau
numbers = [1, 2, 3, 6, 5, 4, 7]
strings = [str[number] for number in numbers]
5Câu lệnh trên giống hệt với dạng chung được giới thiệu ở phần đầu của phần này, nhưng bây giờ có một câu lệnh if ở cuối. Chỉ những mục từ danh sách ban đầu mà biểu thức Boolean là đúng mới được sử dụng làm cơ sở của danh sách mới
Trong ví dụ bên dưới, chúng tôi chọn tất cả các mục chẵn từ danh sách ban đầu làm cơ sở cho danh sách mới. Trên thực tế, những mặt hàng này không được xử lý thêm theo bất kỳ cách nào;
numbers = [1, 1, 2, 3, 4, 6, 4, 5, 7, 10, 12, 3]
even_items = [item for item in numbers if item % 2 == 0]
print[even_items]
đầu ra mẫu
[2, 4, 6, 4, 10, 12]
Biểu thức trong câu lệnh hiểu danh sách ở trên chỉ là một
numbers = [1, 2, 3, 6, 5, 4, 7]
strings = [str[number] for number in numbers]
6 đơn giản, có nghĩa là không có thao tác nào được thực hiện trên các mục trong danh sách. Biểu thức có thể là bất kỳ biểu thức Python nào, giống như trong các ví dụ trước. Ví dụ: câu lệnh hiểu danh sách sau đây lấy tất cả các mục chẵn trong danh sách, nhân mỗi mục với mười và lưu kết quả vào một danh sách mớinumbers = [1, 2, 3, 6, 5, 4, 7]
strings = [str[number] for number in numbers]
1đầu ra mẫu
[20, 40, 60, 40, 100, 120]
Khi bạn gặp nhiều cách hiểu danh sách phức tạp hơn, bạn có thể thấy hữu ích khi thử đọc điều kiện trước. Xét cho cùng, các mục chỉ được xử lý nếu chúng vượt qua bài kiểm tra, do đó, trước tiên, điều hợp lý là tìm ra mục nào vượt qua giai đoạn lọc. Đôi khi, biểu thức trong câu lệnh hiểu danh sách thậm chí không thể thực hiện được đối với tất cả các mục trong danh sách gốc
Ví dụ, phép toán giai thừa chỉ được xác định cho các số nguyên không âm. Nếu chúng ta không thể chắc chắn rằng một danh sách chỉ chứa các giá trị từ 0 trở lên, thì nội dung phải được lọc trước khi chuyển chúng sang hàm giai thừa mà chúng ta đã thực hiện trước đó
numbers = [1, 2, 3, 6, 5, 4, 7]
strings = [str[number] for number in numbers]
2đầu ra mẫu
[6, 24, 120, 1]
Như chúng ta đã thấy trong ví dụ hiểu danh sách đầu tiên của mình, trong đó các số nguyên được chuyển đổi thành chuỗi, các mục trong danh sách mới không nhất thiết phải cùng loại với các mục trong danh sách ban đầu. Tiếp tục từ ví dụ giai thừa ở trên, chúng ta có thể tạo một bộ từ mỗi mục gốc và đối tác được xử lý của nó, đồng thời lưu trữ chúng trong một danh sách, kết hợp mọi thứ chúng ta đã học cho đến nay trong một câu lệnh hiểu danh sách duy nhất
numbers = [1, 2, 3, 6, 5, 4, 7]
strings = [str[number] for number in numbers]
3đầu ra mẫu
[[2, 2], [4, 24], [6, 720]]
Tách ví dụ trên ra, chúng ta có biểu thức Boolean
numbers = [1, 2, 3, 6, 5, 4, 7]
strings = [str[number] for number in numbers]
7. Điều này có nghĩa là chỉ những mục vừa dương vừa chia hết cho hai mới được chấp nhận để xử lý thêm từ danh sách ban đầuNhững số chẵn, dương này sau đó lần lượt được xử lý thành định dạng
numbers = [1, 2, 3, 6, 5, 4, 7]
strings = [str[number] for number in numbers]
8. Đây là một bộ, trong đó mục đầu tiên là chính số đó và mục thứ hai là kết quả được trả về bởi hàm giai thừaĐang tải
Đang tải
Thực thi thay thế với khả năng hiểu danh sách
Thông thường khi chúng ta có một câu điều kiện, chúng ta cũng bao gồm một nhánh
numbers = [1, 2, 3, 6, 5, 4, 7]
strings = [str[number] for number in numbers]
9. Vì chúng ta có thể sử dụng các điều kiện trong việc hiểu danh sách, nên nhánh khác cũng có sẵn với việc hiểu danh sách. Cú pháp chung của điều kiện được sử dụng với khả năng hiểu danh sách trông như thế nàynumbers = list[range[1,10]]
print[numbers]
numbers_multiplied = [number * 10 for number in numbers]
print[numbers_multiplied]
0Chúng ta đã xem qua các câu điều kiện một dòng hoặc toán tử bậc ba này trong phần 7. Biểu thức trên có giá trị là
numbers = list[range[1,10]]
print[numbers]
numbers_multiplied = [number * 10 for number in numbers]
print[numbers_multiplied]
1 hoặc numbers = list[range[1,10]]
print[numbers]
numbers_multiplied = [number * 10 for number in numbers]
print[numbers_multiplied]
2, tùy thuộc vào điều kiện là đúng hay saiĐể ôn lại chủ đề này, nếu chúng tôi cần in ra số lớn hơn trong hai số và chúng tôi chỉ muốn sử dụng một câu lệnh in duy nhất, chúng tôi có thể khớp tất cả trên một dòng
numbers = [1, 2, 3, 6, 5, 4, 7]
strings = [str[number] for number in numbers]
0Kết hợp cú pháp toán tử bậc ba với câu lệnh hiểu danh sách mang lại cấu trúc chung sau
numbers = list[range[1,10]]
print[numbers]
numbers_multiplied = [number * 10 for number in numbers]
print[numbers_multiplied]
3Điều này có vẻ hơi khó hiểu, vì cấu trúc điều kiện giờ xuất hiện trước phần hiểu danh sách thực tế. Đây chỉ là cách cú pháp đã được xác định, ít nhất là tại thời điểm này. Nếu cũng có nhánh
numbers = [1, 2, 3, 6, 5, 4, 7]
strings = [str[number] for number in numbers]
9, điều kiện có trước. Nếu chỉ có một numbers = list[range[1,10]]
print[numbers]
numbers_multiplied = [number * 10 for number in numbers]
print[numbers_multiplied]
5, nó sẽ đi đến cuối. Bạn có thể thử hoán đổi chúng xung quanh và xem điều gì sẽ xảy raBao gồm một toán tử khác có nghĩa là chúng tôi sẽ xử lý lại mọi mục từ danh sách ban đầu. Tùy thuộc vào điều kiện là đúng hay sai,
numbers = list[range[1,10]]
print[numbers]
numbers_multiplied = [number * 10 for number in numbers]
print[numbers_multiplied]
1 hoặc numbers = list[range[1,10]]
print[numbers]
numbers_multiplied = [number * 10 for number in numbers]
print[numbers_multiplied]
2 được thực hiện trên từng mục trong danh sáchVí dụ sau kiểm tra xem các mục trong danh sách có bằng 0 hoặc cao hơn không. Bất kỳ mục nào như vậy đều được chấp nhận, nhưng tất cả các mục tiêu cực đều bị phủ định, do đó, dấu hiệu được thay đổi từ tiêu cực sang tích cực. Kết quả là một danh sách chứa các giá trị tuyệt đối của các mục trong danh sách ban đầu
numbers = [1, 2, 3, 6, 5, 4, 7]
strings = [str[number] for number in numbers]
1đầu ra mẫu
[1, 3, 45, 110, 2, 9, 11]
Nhắc lại những gì xảy ra ở trên. nếu điều kiện
numbers = list[range[1,10]]
print[numbers]
numbers_multiplied = [number * 10 for number in numbers]
print[numbers_multiplied]
8 là đúng, mục sẽ trải qua biểu thức numbers = list[range[1,10]]
print[numbers]
numbers_multiplied = [number * 10 for number in numbers]
print[numbers_multiplied]
9 và kết quả là chính mục đó. Nếu điều kiện là sai, mục sẽ trải qua biểu thức def factorial[n: int]:
""" The function calculates the factorial n! for integers above zero """
k = 1
while n >= 2:
k *= n
n -= 1
return k
if __name__ == "__main__":
numbers = [5, 2, 4, 3, 0]
factorials = [factorial[number] for number in numbers]
print[factorials]
0, để nó trở thành giá trị dươngTrong ví dụ sau, chúng ta có hàm
def factorial[n: int]:
""" The function calculates the factorial n! for integers above zero """
k = 1
while n >= 2:
k *= n
n -= 1
return k
if __name__ == "__main__":
numbers = [5, 2, 4, 3, 0]
factorials = [factorial[number] for number in numbers]
print[factorials]
1 lấy một danh sách làm đối số của nó và trả về một danh sách khác có độ dài bằng bất kỳ chuỗi nào trong danh sách ban đầu. Tuy nhiên, chức năng này phù hợp với các mục danh sách thuộc bất kỳ loại nào. Nếu mục là một chuỗi, nó sẽ tính toán độ dài của nó. Nếu mục là bất kỳ thứ gì khác, nó sẽ chèn -1 vào danh sách mà nó trả về