Đối tượng được trả về range()
(hoặc xrange()
trong Python2.x) được gọi là generator.
Thay vì lưu toàn bộ dải, [0,1,2,..,9]
, trong bộ nhớ, trình tạo lưu trữ định nghĩa cho (i=0; i<10; i+=1)
và tính giá trị tiếp theo chỉ khi cần (đánh giá lười biếng AKA).
Về cơ bản, một máy phát điện cho phép bạn trả về một danh sách như cấu trúc, nhưng đây là một số khác biệt:
- Một danh sách lưu trữ tất cả các yếu tố khi nó được tạo ra. Một máy phát tạo ra phần tử tiếp theo khi cần.
- Danh sách có thể được lặp lại nhiều như bạn cần, chỉ có thể lặp lại máy phát qua chính xác một lần.
- Danh sách có thể lấy các phần tử theo chỉ mục, một trình tạo không thể - nó chỉ tạo ra các giá trị một lần, từ đầu đến cuối.
Một máy phát điện có thể được tạo ra theo hai cách:
(1) Rất giống với một danh sách hiểu:
# this is a list, create all 5000000 x/2 values immediately, uses []
lis = [x/2 for x in range(5000000)]
# this is a generator, creates each x/2 value only when it is needed, uses()
gen = (x/2 for x in range(5000000))
(2) Là một chức năng, sử dụng yield
để trả lại giá trị tiếp theo:
# this is also a generator, it will run until a yield occurs, and return that result.
# on the next call it picks up where it left off and continues until a yield occurs...
def divby2(n):
num = 0
while num < n:
yield num/2
num += 1
# same as (x/2 for x in range(5000000))
print divby2(5000000)
Lưu ý: Mặc dù range(5000000)
là một trình tạo trong Python3.x, [x/2 for x in range(5000000)]
vẫn là một danh sách. range(...)
thực hiện công việc và tạo ra x
mỗi lần, nhưng toàn bộ danh sách các giá trị x/2
sẽ được tính khi danh sách này được tạo.
Tạo một máy phát điện (ví dụ 'def' chứa' yield') gây ra tác dụng phụ như 'print' trước khi nó mang lại giá trị. Sau đó, lặp máy phát điện với độ trễ một giây mỗi lần lặp. Khi nào các bản in xuất hiện? Python '' phạm vi' (giống như 'xrange' trong Python 2) hoạt động như thế: các tính toán không được thực hiện cho đến khi được yêu cầu. Đây là những gì "đánh giá lười biếng" có nghĩa là. – user2864740