Trình lặp lại Python

0
395

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__.

Trình lặp trong Python

Các trình lặp lại ở 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 lại 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 kết thúc 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 (cuộc gọi gần đây nhất cuối cùng):
  Tệp "<string>", dòng 24, trong <module>
    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 vòng lặp, iter_objbằng cách gọi đối tượng có thể lặp iter()lại.

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.

Nếu bạn không có bất kỳ ý tưởng nào về lập trình hướng đối tượng, hãy truy cập  Lập trình hướng đối tượng Python .

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))

Đầu ra

1
2
4
số 8
Traceback (cuộc gọi gần đây nhất cuối cùng):
  Tệp "/home/bsoyuj/Desktop/Untitled-1.py", dòng 32, trong <module>
    in (tiếp theo (i))
  Tệp "<string>", dòng 18, trong __next__
    tăng StopIteration
StopIteration

Chúng ta cũng có thể sử dụng một forvòng lặp để lặp qua lớp trình lặp của chúng ta

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

Trình lặp vô hạn trong Python

Không nhất thiết phải sử dụng hết mục trong đối tượng trình lặp. Có thể có vòng lặp vô hạn (không bao giờ kết thúc). Chúng ta phải cẩn thận khi xử lý các trình vòng lặp như vậy.

Dưới đây là một ví dụ đơn giản để chứng minh trình lặp vô hạn.

Hàm dựng sẵn iter() có thể được gọi với hai đối số trong đó đối số đầu tiên phải là đối tượng có thể gọi (hàm) và đối số thứ hai là sentinel. Trình lặp gọi hàm này cho đến khi giá trị trả về bằng với sentinel.

>>> int()
0

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

Chúng ta có thể thấy rằng int()hàm luôn trả về 0. Vì vậy, việc chuyển nó như iter(int,1)sẽ trả về một trình lặp gọi int()cho đến khi giá trị trả về bằng 1. Điều này không bao giờ xảy ra và chúng ta nhận được một trình lặp vô hạn.

Chúng tôi cũng có thể xây dựng các trình vòng lặp vô hạn của riêng mình. Về mặt lý thuyết, trình lặp sau sẽ trả về tất cả các số lẻ.

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

Một cuộc chạy mẫu sẽ như sau.

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

Và như thế…

Hãy cẩn thận bao gồm điều kiện kết thúc, khi lặp qua các loại trình vòng lặp vô hạn này.

Ưu điểm của việc sử dụng trình vòng 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 (về mặt lý thuyết) trong bộ nhớ hữu hạn.

Khóa học PYTHON (IPD2020) cho người mới bắt đầu