Trình lặp lại Python (__iter__ và __next__): Cách sử dụng và tại sao?

Trình lặp là các đối tượng có thể được lặp lại. Trong hướng dẫn này, bạn sẽ tìm hiểu cách trình vòng lặp hoạt động và cách bạn có thể xây dựng trình vòng lặp của riêng mình bằng cách sử dụng các phương thức __iter__ và __next__.

Video: Trình lặp lại Python

Trình lặp lại bằng Python

Các trình lặp ở khắp mọi nơi trong Python. Chúng được thực hiện một cách trang nhã trong forcác vòng lặp, phần hiểu, bộ tạo, v.v. nhưng được ẩn trong tầm nhìn rõ ràng.

Trình lặp trong Python chỉ đơn giản là một đối tượng có thể được lặp lại. Một đối tượng sẽ trả về dữ liệu, một phần tử tại một thời điểm.

Về mặt kỹ thuật, một đối tượng trình vòng lặp Python phải triển khai hai phương thức đặc biệt __iter__()__next__()được gọi chung là giao thức trình vòng lặp .

Một đối tượng được gọi là có thể lặp lại nếu chúng ta có thể lấy một trình lặp từ nó. Hầu hết các vùng chứa dựng sẵn trong Python như: list, tuple, string, v.v. đều là các tệp lặp.

Các iter()chức năng (mà lần lượt gọi là __iter__()phương pháp) trả về một iterator từ họ.

Lặp lại thông qua một Trình lặp lại

Chúng tôi sử dụng next()hàm để lặp lại thủ công qua tất cả các mục của một trình lặp. Khi chúng ta đến cuối và không còn dữ liệu nào được trả về, nó sẽ nâng lên StopIterationException. Sau đây là một ví dụ.

 # define a list my_list = (4, 7, 0, 3) # get an iterator using iter() my_iter = iter(my_list) # iterate through it using next() # Output: 4 print(next(my_iter)) # Output: 7 print(next(my_iter)) # next(obj) is same as obj.__next__() # Output: 0 print(my_iter.__next__()) # Output: 3 print(my_iter.__next__()) # This will raise error, no items left next(my_iter)

Đầu ra

 4 7 0 3 Traceback (lần gọi gần đây nhất): Tệp "", dòng 24, tiếp theo (my_iter) StopIteration

Một cách thanh lịch hơn để tự động lặp lại là sử dụng vòng lặp for. Sử dụng điều này, chúng ta có thể lặp qua bất kỳ đối tượng nào có thể trả về một trình lặp, ví dụ: danh sách, chuỗi, tệp, v.v.

 >>> for element in my_list:… print(element)… 4 7 0 3

Hoạt động của vòng lặp for cho Trình lặp lại

Như chúng ta thấy trong ví dụ trên, forvòng lặp có thể tự động lặp lại qua danh sách.

Trong thực tế, forvòng lặp có thể lặp qua bất kỳ vòng lặp nào có thể lặp lại. Chúng ta hãy xem xét kỹ hơn cách forvòng lặp thực sự được triển khai trong Python.

 for element in iterable: # do something with element

Thực sự được thực hiện như.

 # create an iterator object from that iterable iter_obj = iter(iterable) # infinite loop while True: try: # get the next item element = next(iter_obj) # do something with element except StopIteration: # if StopIteration is raised, break from loop break

Vì vậy, trong nội bộ, forvòng lặp tạo một đối tượng trình lặp, iter_objbằng cách gọi đối tượng có thể iter()lặp.

Trớ trêu thay, forvòng lặp này thực sự là một vòng lặp while vô hạn.

Bên trong vòng lặp, nó gọi next()để lấy phần tử tiếp theo và thực thi phần thân của forvòng lặp với giá trị này. Sau khi tất cả các mục xả, StopIterationđược nâng lên, được bắt bên trong và kết thúc vòng lặp. Lưu ý rằng bất kỳ loại ngoại lệ nào khác sẽ đi qua.

Xây dựng trình lặp tùy chỉnh

Dễ dàng tạo một trình lặp từ đầu bằng Python. Chúng ta chỉ cần triển khai __iter__()các __next__()phương thức và.

Các __iter__()phương thức trả về đối tượng iterator riêng của mình. Nếu được yêu cầu, một số khởi tạo có thể được thực hiện.

Các __next__()phương pháp phải trả lại mục tiếp theo trong chuỗi. Khi đến cuối và trong các cuộc gọi tiếp theo, nó phải tăng lên StopIteration.

Ở đây, chúng tôi đưa ra một ví dụ sẽ cung cấp cho chúng tôi sức mạnh tiếp theo của 2 trong mỗi lần lặp. Số mũ lũy thừa bắt đầu từ 0 đến một số do người dùng đặt.

If you do not have any idea about object-oriented programming, visit Python Object-Oriented Programming.

 class PowTwo: """Class to implement an iterator of powers of two""" def __init__(self, max=0): self.max = max def __iter__(self): self.n = 0 return self def __next__(self): if self.n <= self.max: result = 2 ** self.n self.n += 1 return result else: raise StopIteration # create an object numbers = PowTwo(3) # create an iterable from the object i = iter(numbers) # Using next to get to the next iterator element print(next(i)) print(next(i)) print(next(i)) print(next(i)) print(next(i))

Output

 1 2 4 8 Traceback (most recent call last): File "/home/bsoyuj/Desktop/Untitled-1.py", line 32, in print(next(i)) File "", line 18, in __next__ raise StopIteration StopIteration

We can also use a for loop to iterate over our iterator class.

 >>> for i in PowTwo(5):… print(i)… 1 2 4 8 16 32

Python Infinite Iterators

It is not necessary that the item in an iterator object has to be exhausted. There can be infinite iterators (which never ends). We must be careful when handling such iterators.

Here is a simple example to demonstrate infinite iterators.

The built-in function iter() function can be called with two arguments where the first argument must be a callable object (function) and second is the sentinel. The iterator calls this function until the returned value is equal to the sentinel.

 >>> int() 0 >>> inf = iter(int,1) >>> next(inf) 0 >>> next(inf) 0

We can see that the int() function always returns 0. So passing it as iter(int,1) will return an iterator that calls int() until the returned value equals 1. This never happens and we get an infinite iterator.

We can also build our own infinite iterators. The following iterator will, theoretically, return all the odd numbers.

 class InfIter: """Infinite iterator to return all odd numbers""" def __iter__(self): self.num = 1 return self def __next__(self): num = self.num self.num += 2 return num

A sample run would be as follows.

 >>> a = iter(InfIter()) >>> next(a) 1 >>> next(a) 3 >>> next(a) 5 >>> next(a) 7

And so on…

Be careful to include a terminating condition, when iterating over these types of infinite iterators.

Ưu điểm của việc sử dụng trình lặp là chúng tiết kiệm tài nguyên. Giống như hình trên, chúng ta có thể lấy tất cả các số lẻ mà không cần lưu trữ toàn bộ hệ thống số trong bộ nhớ. Chúng ta có thể có vô hạn mục (theo lý thuyết) trong bộ nhớ hữu hạn.

Có một cách dễ dàng hơn để tạo trình vòng lặp trong Python. Để tìm hiểu thêm, hãy truy cập: Trình tạo Python sử dụng năng suất.

thú vị bài viết...