Tại sao bạn nên sử dụng Python Generator
Generator đã là một phần quan trọng của Python kể từ khi được giới thiệu với PEP 255.
Generator function cho phép bạn tuyên bố một function hoạt động giống như một iterator.
Chúng cho phép các lập trình tạo ra một iterator một cách nhanh chóng và dễ dàng.
Iterator là gì, bạn có thể yêu cầu?
Iterator là một đối tượng có thể lặp lại (looped). Nó được sử dụng để phản ánh một container dữ liệu để làm cho nó hoạt động giống như một đối tượng iterable. Có thể bạn đã sử dụng một vài đối tượng có thể lặp lại mỗi ngày: các string, list và từ điển để đặt tên cho một số.
Một iterator được định nghĩa bởi một class thực hiện các Iterator Protocol. Giao thức này chỉ ra hai phương pháp trong class: __iter__
và __next__
.
Quay lại. Tại sao bạn thậm chí muốn tạo ra iterators?
Tiết kiệm không gian bộ nhớ
Các iterator không tính toán giá trị của mỗi mục khi khởi tạo. Chúng chỉ tính toán nó khi bạn yêu cầu nó. Đây được gọi là lazy evaluation.
Lazy evaluation thực sự hữu ích khi bạn có một bộ dữ liệu cực lớn để tính toán. Nó cho phép bạn sử dụng dữ liệu ngay lập tức, trong khi cả bộ dữ liệu đang được tính.
Giả sử chúng ta muốn nhận được tất cả các số nguyên tố nhỏ hơn một số cực đại.
Trước tiên chúng ta xác định hàm kiểm tra nếu một số là số nguyên tố:
def check_prime(number): for divisor in range(2, int(number ** 0.5) + 1): if number % divisor == 0: return False return True
Sau đó, chúng ta định nghĩa class bao gồm phương thức __iter__
và __next__
:
class Primes: def __init__(self, max): self.max = max self.number = 1 def __iter__(self): return self def __next__(self): self.number += 1 if self.number >= self.max: raise StopIteration elif check_prime(self.number): return self.number else: return self.__next__()
Primes
được khởi tạo với giá trị lớn nhất. Nếu số nguyên lớn tiếp theo lớn hơn mức max
, iterator sẽ tăng một ngoại lệ StopIteration
, kết thúc Iterator.
Khi chúng ta yêu cầu các element tiếp theo trong Iterator, nó sẽ tăng number
một đơn vị và kiểm tra xem đó có là một số nguyên tố. Nếu không, nó sẽ gọi __next__
một lần nữa cho đến khi number
đó là số nguyên tố. Một khi đạt được, Iterator trả về số.
Bằng cách sử dụng một Iterator, chúng ta không tạo ra một danh sách các số nguyên tố trong bộ nhớ của chúng ta. Thay vào đó, chúng tôi sẽ tạo ra số nguyên tố tiếp theo mỗi khi được yêu cầu.
Hãy thử nó:
primes = Primes(100000000000) print(primes) for x in primes: print(x) --------- <__main__.Primes object at 0x1021834a8> 2 3 5 7 11 ...
Mỗi lần lặp của đối tượng Primes
gọi __next__
để tạo ra số nguyên tố tiếp theo.
Iterator chỉ có thể được lặp lại qua một lần. Nếu bạn cố lặp lại primes
một lần nữa, sẽ không có giá trị nào được trả về và điều này hoạt động giống như một danh sách trống rỗng.
Bây giờ chúng ta đã biết iterator là gì và làm thế nào để tạo ra chúng, tiếp theo là về generator.
Generator
Nhớ lại rằng generator function cho phép chúng ta tạo ra các iterator theo một cách đơn giản hơn.
Generator giới thiệu câu lệnh yield
cho Python. Nó hoạt động giống như return
vì nó trả về một giá trị.
Vậy là chúng ta đã tiết kiệm được trạng thái của function. Trong lần tiếp theo function được gọi, vẫn tiếp tục từ nơi dừng lại, với cùng các giá trị biến mà nó đã có trước khi yielding.
Nếu chúng ta chuyển Primes
iterator thành generator, nó sẽ giống như sau
def Primes(max): number = 1 while number < max: number += 1 if check_prime(number): yield number primes = Primes(100000000000) print(primes) for x in primes: print(x) --------- <generator object Primes at 0x10214de08> 2 3 5 7 11 ...
Bây giờ đó là pythonic! Liệu ta có thể làm tốt hơn không?
Vậy, chúng ta có thể sử dụng Generator Expressions, được giới thiệu với PEP 289.
Đây là danh sách comprehension equivalent của generator. Nó hoạt động chính xác giống như comprehension, nhưng biểu thức được đặt trong()
và trái ngược với []
.
Các biểu thức sau đây có thể thay thế generator function ở trên:
primes = (i for i in range(2, 100000000000) if check_prime(i)) print(primes) for x in primes: print(x) --------- <generator object <genexpr> at 0x101868e08> 2 3 5 7 11 ...
Đây là khả năng của generator bằng Python.
Tóm lại
- Generator cho phép bạn tạo các iterator theo cách rất pythonic.
- Iterator cho phép lazy evaluation, chỉ tạo ra element tiếp theo của một đối tượng có thể lặp lại khi được yêu cầu. Điều này hữu ích đối với bộ dữ liệu cực lớn.
- Iterator và generator chỉ có thể lặp lại được một lần.
- Generator Function tốt hơn Iterator.
- Generator Expressions tốt hơn các Iterator (đối với các trường hợp đơn giản).
Nguồn: TopDev via Freecodecamp
Xem thêm tuyển dụng lập trình python lương up to 20M
- F Framework nào tốt nhất cho dự án của bạn? – Checklist chi tiết
- K Kinh nghiệm xử lý responsive table hiệu quả
- S Stackoverflow là gì? Bí kíp tận dụng Stack Overflow hiệu quả
- 7 7 kinh nghiệm hữu ích khi làm việc với GIT trong dự án
- B Bài tập Python từ cơ bản đến nâng cao (có lời giải)
- B Bảo mật API là gì? Một số nguyên tắc và kỹ thuật cần biết
- H Hướng dẫn cài đặt và tự học lập trình Python cơ bản từ A-Z
- C Chinh Phục Phân Tích Dữ Liệu Với Pandas Trong Python: Hướng Dẫn Từng Bước
- D Display CSS là gì? Cách khai báo và sử dụng thuộc tính display trong CSS
- C Compiler là gì? Công việc cụ thể của một trình biên dịch