Năng suất Python không có vòng lặp

Trong Python,

7 được sử dụng để trả về từ một hàm mà không hủy các biến của nó. Theo một nghĩa nào đó,
7 tạm dừng việc thực thi chức năng. Khi hàm được gọi lại, việc thực thi tiếp tục từ câu lệnh
7 cuối cùng

Sử dụng

7 biến một chức năng thành một trình tạo. Dưới đây là một minh họa về chức năng so với. máy phát điện

An illustration of generator execution

Hình ảnh của tác giả

Trình tạo trả về một đối tượng trình tạo, còn được gọi là trình vòng lặp, tạo ra một giá trị tại một thời điểm. Nó không lưu trữ bất kỳ giá trị. Điều này làm cho bộ nhớ máy phát hiệu quả

Ví dụ: bạn có thể sử dụng trình tạo để lặp qua một nhóm số mà không lưu bất kỳ số nào trong bộ nhớ

Cách biến một chức năng thành một trình tạo

Để biến một hàm thành một trình tạo, hãy

7 một giá trị thay vì trả về giá trị đó. Điều này làm cho hàm trả về một đối tượng trình tạo. Đây là một trình vòng lặp mà bạn có thể lặp qua như một danh sách

Thí dụ

Hãy tạo một hàm

print(next(squared_numbers))
2 bình phương danh sách đầu vào gồm các số

đầu ra

[1, 4, 9, 16, 25]

Hãy biến chức năng này thành một trình tạo. Thay vì lưu trữ các số bình phương vào một danh sách, bạn có thể

7 giá trị một lần mà không cần lưu trữ chúng

đầu ra

Bây giờ bạn không còn nhận được danh sách các số bình phương. Điều này là do kết quả

print(next(squared_numbers))
4 là một đối tượng trình tạo

Sử dụng hàm next() để lấy các giá trị

Đối tượng trình tạo không chứa số trong bộ nhớ. Thay vào đó, nó tính toán và

print(next(squared_numbers))
5 một kết quả tại một thời điểm. Nó chỉ thực hiện điều này khi bạn yêu cầu giá trị tiếp theo bằng cách sử dụng hàm
print(next(squared_numbers))
6

Hãy yêu cầu trình tạo tính toán số bình phương đầu tiên

print(next(squared_numbers))

đầu ra

1

Hãy làm cho nó tính các số còn lại bằng cách gọi

print(next(squared_numbers))
6 bốn lần nữa

print(next(squared_numbers))
print(next(squared_numbers))
print(next(squared_numbers))
print(next(squared_numbers))

đầu ra

4
9
16
25

Bây giờ trình tạo đã bình phương tất cả các số. Nếu bạn gọi

print(next(squared_numbers))
6 một lần nữa

print(next(squared_numbers))

Xảy ra lỗi

Traceback (most recent call last):
File "", line 13, in
StopIteration

Lỗi này cho bạn biết không còn số nào được bình phương. Nói cách khác, máy phát điện đã cạn kiệt

Bây giờ bạn đã hiểu cách một trình tạo hoạt động và cách làm cho nó tính toán các giá trị

Không sử dụng hàm next()

Sử dụng hàm

print(next(squared_numbers))
6 thể hiện rõ cách thức hoạt động của trình tạo

Trên thực tế, bạn không cần gọi hàm

print(next(squared_numbers))
6. Thay vào đó, bạn có thể sử dụng vòng lặp
1
1 với cùng cú pháp mà bạn sẽ sử dụng nếu bạn lặp qua một danh sách (vòng lặp
1
1 gọi hàm
print(next(squared_numbers))
6 cho bạn)

Chẳng hạn, hãy lặp lại ví dụ về trình tạo bằng vòng lặp

1
1

đầu ra

1
4
9
16
25

Dòng số vô tận với máy phát điện

Các đối tượng trình tạo (iterators) chỉ quan tâm đến giá trị hiện tại và không lưu trữ bất kỳ giá trị nào. Do đó, có thể tạo ra một dòng giá trị vô hạn

Thí dụ

Hãy tạo một trình tạo vô hạn tạo ra tất cả các số sau điểm bắt đầu

def infinite_values(start):
current = start
while True:
yield current
current += 1

Trình tạo này tạo ra các giá trị từ

1
5 đến vô cùng. Hãy chạy nó

0

đầu ra

1

Về mặt cú pháp, nó xuất hiện

1
6 là một danh sách vô hạn các số mà chúng tôi đang lặp lại. Trên thực tế, đó là một trình tạo tính toán từng giá trị một

Máy phát điện vs. Danh sách—So sánh thời gian chạy

Hãy thực hiện so sánh thời gian chạy giữa các trình tạo và hàm

Trong ví dụ này, có một danh sách gồm mười số và hai hàm

  • Hàm
    1
    7 chọn ngẫu nhiên một số từ danh sách
    1
    8 lần
  • Hàm tạo
    1
    9 cũng chọn ngẫu nhiên một số từ danh sách
    1
    8 lần

Mã này so sánh thời gian chạy của việc sử dụng các hàm này để tạo danh sách 1 triệu số được chọn ngẫu nhiên

Kết quả

2

Điều này cho thấy cách một trình tạo nhanh hơn để tạo. Điều này là do khi bạn tạo danh sách, tất cả các số phải được lưu trong bộ nhớ. Nhưng khi bạn sử dụng trình tạo, các số không được lưu trữ ở bất kỳ đâu, vì vậy nó nhanh như chớp

Khi sử dụng Trình tạo trong Python

Để biết khi nào bạn có thể sử dụng máy phát điện, hãy tự hỏi: “Tôi có cần nhiều mục cùng một lúc không?”

Quay lại ví dụ về bình phương số. Nếu bạn muốn in các số bình phương, bạn có thể sử dụng trình tạo. Điều này là do các số bình phương không phụ thuộc vào nhau. Vì vậy, bạn có thể tính toán từng cái một

Nếu danh sách nhỏ, nó không tạo ra sự khác biệt cho dù bạn có sử dụng trình tạo hay không. Nhưng khi kích thước danh sách lớn hơn, sức mạnh của trình tạo sẽ phát huy tác dụng

Hãy nghĩ về việc lặp qua một tệp chứa một tỷ chuỗi (ví dụ: mật khẩu). Không có cách nào bạn có thể lưu trữ số lượng chuỗi đó vào một danh sách. Trong trường hợp này, bạn có thể sử dụng trình tạo để lặp qua từng cái một mà không cần lưu trữ tất cả chúng cùng một lúc

Viết tắt để tạo trình tạo

Cuối cùng, hãy xem cách bạn có thể rút ngắn mã của mình khi xử lý trình tạo

Hàm

print(next(squared_numbers))
2 mà bạn đã thấy trước đó giới thiệu các dòng mã thừa

Thay vì tạo một hàm, bạn có thể sử dụng danh sách để lưu sáu dòng mã

đầu ra

[1, 4, 9, 16, 25]

Một tốc ký tương tự cũng có thể được sử dụng với máy phát điện

Mức độ hiểu trình tạo, hay còn gọi là biểu thức trình tạo, là cách viết tắt để tạo trình tạo. Cú pháp tương tự như cú pháp hiểu danh sách

Trước đây, bạn đã xác định trình tạo

print(next(squared_numbers))
2 theo cách này

Nhưng bạn có thể sử dụng biểu thức trình tạo để thực hiện chính xác như vậy

Kết quả

4

Để in

print(next(squared_numbers))
4, bạn có thể lặp qua trình tạo

5

đầu ra

1
4
9
16
25

Phần kết luận

Trong Python,

7 là từ khóa biến hàm thành trình tạo

Không giống như một danh sách, một trình tạo không lưu trữ các giá trị. Thay vào đó, nó biết giá trị hiện tại và cách lấy giá trị tiếp theo. Điều này làm cho bộ nhớ máy phát hiệu quả

Cú pháp lặp qua một trình tạo giống như lặp qua một danh sách

Sử dụng trình tạo có thể hữu ích bất cứ khi nào bạn lặp qua một nhóm lớn các mục và bạn không cần lưu trữ tất cả chúng cùng một lúc