Thứ sáu, 24/07/2020 | 00:00 GMT+7

Cách sử dụng hàm bộ lọc Python

Hàm filter() hợp sẵn trong Python được dùng để tạo một trình lặp mới từ một trình lặp hiện có (như danh sách hoặc từ điển ) sẽ lọc ra các phần tử một cách hiệu quả bằng cách sử dụng một hàm mà ta cung cấp. Một iterable là một đối tượng Python có thể được “lặp qua”, nghĩa là , nó sẽ trở lại các mục trong một chuỗi như vậy mà ta có thể sử dụng nó trong một for vòng lặp.

Cú pháp cơ bản cho hàm filter() là:

filter(function, iterable) 

Kết quả sẽ trả về một đối tượng bộ lọc, là một đối tượng có thể lặp lại. Ta có thể sử dụng một hàm như list() để tạo danh sách tất cả các mục được trả về trong một đối tượng bộ lọc.

Hàm filter() cung cấp một cách lọc các giá trị thường có thể hiệu quả hơn cách hiểu danh sách , đặc biệt khi ta bắt đầu làm việc với các tập dữ liệu lớn hơn. Ví dụ, một danh sách hiểu được sẽ tạo ra một danh sách mới, điều này sẽ làm tăng thời gian chạy cho quá trình xử lý đó. Điều này nghĩa là sau khi hiểu danh sách của ta đã hoàn thành biểu thức của nó, ta sẽ có hai danh sách trong bộ nhớ. Tuy nhiên, filter() sẽ tạo một đối tượng đơn giản chứa tham chiếu đến danh sách ban đầu, hàm được cung cấp và index về vị trí cần đến trong danh sách root , điều này sẽ chiếm ít bộ nhớ hơn.

Trong hướng dẫn này, ta sẽ xem xét bốn cách khác nhau để sử dụng filter() : với hai cấu trúc có thể lặp lại khác nhau, với một hàm lambda và không có hàm nào được xác định.

Sử dụng filter() với một hàm

Đối số đầu tiên của filter() là một hàm mà ta sử dụng để quyết định đưa vào hay lọc ra từng mục. Hàm được gọi một lần cho mọi mục trong biến có thể lặp được truyền làm đối số thứ hai và mỗi khi nó trả về False , giá trị sẽ bị giảm xuống. Vì đối số này là một hàm, ta có thể truyền một hàm bình thường hoặc ta có thể sử dụng các hàm lambda , đặc biệt khi biểu thức ít phức tạp hơn.

Sau đây là cú pháp của lambda với filter() :

filter(lambda item: item[] expression, iterable) 

Với một danh sách, như sau, ta có thể kết hợp một hàm lambda với một biểu thức mà ta muốn đánh giá từng mục từ danh sách:

creature_names = ['Sammy', 'Ashley', 'Jo', 'Olly', 'Jackie', 'Charlie'] 

Để lọc danh sách này để tìm tên của các sinh vật thủy sinh bắt đầu bằng một nguyên âm, ta có thể chạy hàm lambda sau:

print(list(filter(lambda x: x[0].lower() in 'aeiou', creature_names))) 

Ở đây ta khai báo một mục trong danh sách của ta là x . Sau đó, ta cài đặt biểu thức của bạn để truy cập ký tự đầu tiên của mỗi chuỗi (hoặc ký tự “no” ), vì vậy x[0] . Giảm bớt trường hợp của mỗi tên đảm bảo điều này sẽ khớp các chữ cái với chuỗi trong biểu thức của ta , 'aeiou' .

Cuối cùng ta vượt qua iterable creature_names . Giống như trong phần trước, ta áp dụng list() vào kết quả để tạo một danh sách từ các trả về của filter() lặp filter() .

Đầu ra sẽ như sau:

Output
['Ashley', 'Olly']

Kết quả tương tự có thể đạt được bằng cách sử dụng một hàm ta xác định:

creature_names = ['Sammy', 'Ashley', 'Jo', 'Olly', 'Jackie', 'Charlie']  def names_vowels(x):   return x[0].lower() in 'aeiou'  filtered_names = filter(names_vowels, creature_names)  print(list(filtered_names)) 

Chức năng của ta names_vowels định nghĩa khái niệm mà ta sẽ thực hiện để lọc creature_names .

, kết quả sẽ như sau:

Output
['Ashley', 'Olly']

Nhìn chung, lambda hàm lambda đạt được kết quả tương tự với filter() như khi ta sử dụng một hàm thông thường. Sự cần thiết phải xác định một hàm thông thường tăng lên khi độ phức tạp của các biểu thức để lọc dữ liệu của ta tăng lên, điều này có khả năng thúc đẩy khả năng đọc tốt hơn trong mã của ta .

Sử dụng Nonefilter()

Ta có thể chuyển None làm đối số đầu tiên cho filter() để trình vòng lặp được trả về lọc ra bất kỳ giá trị nào mà Python coi là "sai". Nói chung, Python coi bất kỳ thứ gì có độ dài bằng 0 (chẳng hạn như danh sách trống hoặc chuỗi trống) hoặc số tương đương với 0 là sai, do đó, việc sử dụng thuật ngữ “falsy”.

Trong trường hợp sau, ta muốn lọc danh sách của bạn để chỉ hiển thị số bể tại bể cá của ta :

aquarium_tanks = [11, False, 18, 21, "", 12, 34, 0, [], {}] 

Trong đoạn mã này, ta có một danh sách chứa các số nguyên , dãy trống và giá trị boolean .

filtered_tanks = filter(None, aquarium_tanks) 

Ta sử dụng các filter() chức năng với None và vượt qua trong aquarium_tanks danh sách như iterable của ta . Vì ta đã chuyển None làm đối số đầu tiên, ta sẽ kiểm tra xem các mục trong danh sách của ta có bị coi là sai hay không.

print(list(filtered_tanks)) 

Sau đó, ta bọc filtered_tanks trong một hàm list() để nó trả về một danh sách cho các filtered_tanks khi ta in.

Ở đây kết quả chỉ hiển thị các số nguyên. Tất cả các mục được đánh giá là False , tương đương với độ dài bằng 0 , đã bị loại bỏ bởi filter() :

Output
[11, 25, 18, 21, 12, 34]

Lưu ý : Nếu ta không sử dụng list() và print filtered_tanks ta sẽ nhận được một đối tượng filter giống như sau: <filter object at 0x7fafd5903240> . Đối tượng bộ lọc là một đối tượng có thể lặp lại, vì vậy ta có thể lặp lại nó với for hoặc ta có thể sử dụng list() để biến nó thành một danh sách, ta đang làm ở đây vì đó là một cách tốt để xem lại kết quả.

Với None ta đã sử dụng filter() để nhanh chóng xóa các mục khỏi danh sách bị coi là sai.

Sử dụng filter() với Danh sách Từ điển

Khi ta có cấu trúc dữ liệu phức tạp hơn, ta vẫn có thể sử dụng filter() để đánh giá từng mục. Ví dụ: nếu ta có một danh sách các từ điển, ta không chỉ muốn lặp lại từng mục trong danh sách - một trong các từ điển - mà ta còn có thể cần lặp lại từng cặp khóa: giá trị trong từ điển để đánh giá tất cả dữ liệu.

Ví dụ: giả sử ta có danh sách từng sinh vật trong bể cá của bạn cùng với các chi tiết khác nhau về từng sinh vật trong số chúng:

aquarium_creatures = [   {"name": "sammy", "species": "shark", "tank number": "11", "type": "fish"},   {"name": "ashley", "species": "crab", "tank number": "25", "type": "shellfish"},   {"name": "jo", "species": "guppy", "tank number": "18", "type": "fish"},   {"name": "jackie", "species": "lobster", "tank number": "21", "type": "shellfish"},   {"name": "charlie", "species": "clownfish", "tank number": "12", "type": "fish"},   {"name": "olly", "species": "green turtle", "tank number": "34", "type": "turtle"} ] 

Ta muốn lọc dữ liệu này bằng một chuỗi tìm kiếm mà ta cung cấp cho hàm. Để có filter() truy cập từng từ điển và từng mục trong từ điển, ta xây dựng một hàm lồng nhau, như sau:

def filter_set(aquarium_creatures, search_string):     def iterator_func(x):         for v in x.values():             if search_string in v:                 return True         return False     return filter(iterator_func, aquarium_creatures) 

Ta định nghĩa một filter_set() chức năng mà mất aquarium_creaturessearch_string như thông số. Trong filter_set() ta chuyển iterator_func() làm hàm để filter() . Hàm filter_set() sẽ trả về trình lặp kết quả từ filter() .

iterator_func() lấy x làm đối số, đại diện cho một mục trong danh sách của ta (nghĩa là một từ điển duy nhất).

Tiếp theo for vòng lặp truy cập các giá trị trong mỗi phím: cặp giá trị trong từ điển của ta và sau đó sử dụng một tuyên bố có điều kiện để kiểm tra xem các search_string là trong v , đại diện cho một giá trị.

Giống như trong các ví dụ trước của ta , nếu biểu thức đánh giá là True , hàm sẽ thêm mục vào đối tượng bộ lọc. Kết quả sẽ trả về sau khi hàm filter_set() hoàn thành. Ta đặt vị trí return False bên ngoài vòng lặp của ta để nó kiểm tra mọi mục trong mỗi từ điển, thay vì quay lại sau khi kiểm tra từ điển đầu tiên.

Ta gọi filter_set() với danh sách các từ điển của ta và chuỗi tìm kiếm mà ta muốn tìm các kết quả phù hợp:

filtered_records = filter_set(aquarium_creatures, "2")     

Một khi các chức năng hoàn thành ta có đối tượng bộ lọc của ta được lưu trữ trong filtered_records biến, mà ta biến thành một danh sách và in:

print(list(filtered_records))       

Ta sẽ nhận được kết quả sau từ chương trình này:

Output
[{'name': 'ashley', 'species': 'crab', 'tank number': '25', 'type': 'shellfish'}, {'name': 'jackie', 'species': 'lobster', 'tank number': '21', 'type': 'shellfish'}, {'name': 'charlie', 'species': 'clownfish', 'tank number': '12', 'type': 'fish'}]

Ta đã lọc danh sách các từ điển với chuỗi tìm kiếm 2 . Ta có thể thấy rằng ba từ điển bao gồm một số xe tăng với 2 đã được trả lại. Sử dụng chức năng lồng nhau của riêng ta cho phép ta truy cập mọi mục và kiểm tra hiệu quả từng mục đối với chuỗi tìm kiếm.

Kết luận

Trong hướng dẫn này, ta đã học các cách khác nhau để sử dụng hàm filter() trong Python. Như vậy, bạn có thể sử dụng filter() với hàm của riêng mình, hàm lambda hoặc với None để lọc các mục có độ phức tạp khác nhau của cấu trúc dữ liệu.

Mặc dù trong hướng dẫn này, ta đã in kết quả từ filter() ngay lập tức ở định dạng danh sách, nhưng có khả năng trong chương trình của ta , ta sẽ sử dụng đối tượng filter() trả về và thao tác thêm với dữ liệu.

Nếu bạn muốn tìm hiểu thêm về Python, hãy xem loạt bài Cách viết mã trong Python 3trang chủ đề Python của ta .


Tags:

Các tin liên quan

Cách sử dụng module pathlib để thao tác đường dẫn hệ thống tệp trong Python 3
2020-07-15
Cách tạo Slackbot bằng Python trên Ubuntu 20.04
2020-06-30
Cách sử dụng ThreadPoolExecutor trong Python 3
2020-06-23
Cách sử dụng module sqlite3 trong Python 3
2020-06-02
Cách thiết lập notebook Jupyter với Python 3 trên Ubuntu 20.04 và Kết nối qua Đường hầm SSH
2020-05-19
Cách cài đặt Phân phối Python Anaconda trên Ubuntu 20.04 [Khởi động nhanh]
2020-05-19
Cách cài đặt Phân phối Python Anaconda trên Ubuntu 20.04
2020-05-06
Cách cài đặt Python 3 và thiết lập môi trường lập trình trên server Ubuntu 20.04
2020-04-24
Cách cài đặt Python 3 và thiết lập môi trường lập trình trên server Ubuntu 18.04
2020-04-24
Cách cài đặt Python 3 và thiết lập môi trường lập trình trên Ubuntu 20.04 [Quickstart]
2020-04-24