Trình tạo Python với một vòng lặp

0
3

Thông thường, các chức năng của bộ tạo được thực hiện với một vòng lặp có điều kiện kết thúc phù hợp.

Hãy lấy một ví dụ về một trình tạo đảo ngược một chuỗi.

def rev_str(my_str):
    length = len(my_str)
    for i in range(length - 1, -1, -1):
        yield my_str[i]


# For loop to reverse the string
for char in rev_str("hello"):
    print(char)

Đầu ra

o
l
l
e
h

Trong ví dụ này, chúng tôi đã sử dụng range()hàm để lấy chỉ mục theo thứ tự ngược lại bằng cách sử dụng vòng lặp for.

Lưu ý : Hàm trình tạo này không chỉ hoạt động với chuỗi mà còn với các loại lặp khác như danh sách , tuple , v.v.

Biểu thức trình tạo Python

Máy phát điện đơn giản có thể được tạo dễ dàng bằng cách sử dụng các biểu thức máy phát điện. Nó làm cho việc xây dựng máy phát điện trở nên dễ dàng.

Tương tự như các hàm lambda tạo ra các hàm ẩn danh , các biểu thức trình tạo tạo các hàm tạo ẩn danh.

Cú pháp cho biểu thức trình tạo tương tự như cú pháp của một danh sách hiểu trong Python . Nhưng dấu ngoặc vuông được thay thế bằng dấu ngoặc tròn.

Sự khác biệt chính giữa khả năng hiểu danh sách và biểu thức trình tạo là khả năng hiểu danh sách tạo ra toàn bộ danh sách trong khi biểu thức trình tạo tạo ra một mục tại một thời điểm.

Họ lười thực hiện (chỉ sản xuất các mặt hàng khi được yêu cầu). Vì lý do này, một biểu thức tạo bộ nhớ hiệu quả hơn nhiều so với một khả năng hiểu danh sách tương đương.

# Initialize the list
my_list = [1, 3, 6, 10]

# square each term using list comprehension
list_ = [x**2 for x in my_list]

# same thing can be done using a generator expression
# generator expressions are surrounded by parenthesis ()
generator = (x**2 for x in my_list)

print(list_)
print(generator)

Đầu ra

[1, 9, 36, 100]
<đối tượng trình tạo <genexpr> tại 0x7f5d4eb4bf50>

Ở trên chúng ta có thể thấy rằng biểu thức trình tạo không tạo ra kết quả cần thiết ngay lập tức. Thay vào đó, nó trả về một đối tượng máy phát điện, đối tượng này chỉ sản xuất các mặt hàng theo yêu cầu.

Đây là cách chúng tôi có thể bắt đầu nhận các mục từ trình tạo:

# Initialize the list
my_list = [1, 3, 6, 10]

a = (x**2 for x in my_list)
print(next(a))

print(next(a))

print(next(a))

print(next(a))

next(a)

Khi chúng tôi chạy chương trình trên, chúng tôi nhận được kết quả sau:

1
9
36
100
Traceback (cuộc gọi gần đây nhất cuối cùng):
  Tệp "<string>", dòng 15, trong <module>
StopIteration

Biểu thức trình tạo có thể được sử dụng làm đối số hàm. Khi sử dụng theo cách này, dấu ngoặc tròn có thể bị bỏ đi.

>>> sum(x**2 for x in my_list)
146

>>> max(x**2 for x in my_list)
100

Sử dụng Trình tạo Python

Có một số lý do làm cho máy phát điện trở thành một triển khai mạnh mẽ.

1. Dễ dàng thực hiện

Trình tạo có thể được triển khai một cách rõ ràng và ngắn gọn so với đối tác lớp trình vòng lặp của chúng. Dưới đây là một ví dụ để thực hiện một chuỗi lũy thừa của 2 bằng cách sử dụng một lớp trình lặp.

class PowTwo:
    def __init__(self, max=0):
        self.n = 0
        self.max = max

    def __iter__(self):
        return self

    def __next__(self):
        if self.n > self.max:
            raise StopIteration

        result = 2 ** self.n
        self.n += 1
        return result

Chương trình trên dài và khó hiểu. Bây giờ, chúng ta hãy làm tương tự bằng cách sử dụng một hàm máy phát điện.

def PowTwoGen(max=0):
    n = 0
    while n < max:
        yield 2 ** n
        n += 1

Vì trình tạo tự động theo dõi các chi tiết, việc triển khai ngắn gọn và gọn gàng hơn nhiều.

2. Bộ nhớ hiệu quả

Một hàm thông thường để trả về một chuỗi sẽ tạo ra toàn bộ chuỗi trong bộ nhớ trước khi trả về kết quả. Đây là mức quá mức cần thiết, nếu số lượng các mục trong chuỗi là rất lớn.

Việc triển khai các trình tự như vậy của trình tạo là thân thiện với bộ nhớ và được ưa thích hơn vì nó chỉ tạo ra một mục tại một thời điểm.

3. Đại diện cho Dòng vô hạn

Máy phát điện là phương tiện tuyệt vời để đại diện cho một luồng dữ liệu vô hạn. Các luồng vô hạn không thể được lưu trữ trong bộ nhớ và vì các bộ tạo chỉ tạo ra một mục tại một thời điểm, chúng có thể đại diện cho một luồng dữ liệu vô hạn.

Hàm tạo sau đây có thể tạo ra tất cả các số chẵn (ít nhất là trên lý thuyết).

def all_even():
    n = 0
    while True:
        yield n
        n += 2

4. Máy phát điện đường ống

Nhiều máy phát điện có thể được sử dụng để vận hành một loạt các hoạt động. Điều này được minh họa tốt nhất bằng cách sử dụng một ví dụ.

Giả sử chúng ta có một trình tạo ra các số trong chuỗi Fibonacci. Và chúng tôi có một máy phát điện khác cho các số bình phương.

Nếu chúng ta muốn tìm ra tổng bình phương của các số trong chuỗi Fibonacci, chúng ta có thể thực hiện theo cách sau đây bằng cách kết hợp đầu ra của các hàm trình tạo với nhau.

def fibonacci_numbers(nums):
    x, y = 0, 1
    for _ in range(nums):
        x, y = y, x+y
        yield x

def square(nums):
    for num in nums:
        yield num**2

print(sum(square(fibonacci_numbers(10))))

Đầu ra

4895

Pipelining này hiệu quả và dễ đọc (và vâng, mát hơn rất nhiều!).


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

LEAVE A REPLY

Please enter your comment!
Please enter your name here