Sự hiểu biết của máy phát điện làm gì? Làm thế nào nó hoạt động? Tôi không thể tìm thấy một hướng dẫn về nó.
Sự hiểu biết của máy phát điện làm gì? Làm thế nào nó hoạt động? Tôi không thể tìm thấy một hướng dẫn về nó.
Câu trả lời:
Bạn có hiểu toàn bộ danh sách không? Nếu vậy, biểu thức trình tạo giống như một danh sách hiểu được, nhưng thay vì tìm tất cả các mục bạn quan tâm và đóng gói chúng vào danh sách, nó sẽ đợi và đưa ra từng mục ra khỏi biểu thức, từng mục một.
>>> my_list = [1, 3, 5, 9, 2, 6]
>>> filtered_list = [item for item in my_list if item > 3]
>>> print(filtered_list)
[5, 9, 6]
>>> len(filtered_list)
3
>>> # compare to generator expression
...
>>> filtered_gen = (item for item in my_list if item > 3)
>>> print(filtered_gen) # notice it's a generator object
<generator object <genexpr> at 0x7f2ad75f89e0>
>>> len(filtered_gen) # So technically, it has no length
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: object of type 'generator' has no len()
>>> # We extract each item out individually. We'll do it manually first.
...
>>> next(filtered_gen)
5
>>> next(filtered_gen)
9
>>> next(filtered_gen)
6
>>> next(filtered_gen) # Should be all out of items and give an error
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
>>> # Yup, the generator is spent. No values for you!
...
>>> # Let's prove it gives the same results as our list comprehension
...
>>> filtered_gen = (item for item in my_list if item > 3)
>>> gen_to_list = list(filtered_gen)
>>> print(gen_to_list)
[5, 9, 6]
>>> filtered_list == gen_to_list
True
>>>
Bởi vì một biểu thức bộ tạo chỉ phải mang lại một mục tại một thời điểm, nó có thể dẫn đến tiết kiệm lớn trong việc sử dụng bộ nhớ. Biểu thức trình tạo có ý nghĩa nhất trong các tình huống mà bạn cần lấy từng mục một, thực hiện nhiều phép tính dựa trên mục đó, sau đó chuyển sang mục tiếp theo. Nếu bạn cần nhiều hơn một giá trị, bạn cũng có thể sử dụng một biểu thức trình tạo và lấy một vài giá trị cùng một lúc. Nếu bạn cần tất cả các giá trị trước khi chương trình của bạn tiếp tục, hãy sử dụng cách hiểu danh sách để thay thế.
next(...)
thay vì .__next__()
bằng Python 3.
If you need more than one value, you can also use a generator expression and grab a few at a time
. Bạn có thể vui lòng cho một ví dụ về cách sử dụng này? Cảm ơn.
Khả năng hiểu của trình tạo là phiên bản lười biếng của khả năng hiểu danh sách.
Nó cũng giống như một sự hiểu danh sách ngoại trừ việc nó trả về một trình lặp thay vì danh sách, tức là một đối tượng có phương thức next () sẽ mang lại phần tử tiếp theo.
Nếu bạn không quen với việc hiểu danh sách, hãy xem tại đây và đối với máy phát điện xem tại đây .
Khả năng hiểu danh sách / trình tạo là một cấu trúc mà bạn có thể sử dụng để tạo danh sách / trình tạo mới từ danh sách hiện có.
Giả sử bạn muốn tạo danh sách các ô vuông của mỗi số từ 1 đến 10. Bạn có thể thực hiện việc này bằng Python:
>>> [x**2 for x in range(1,11)]
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
ở đây, range(1,11)
tạo danh sách [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
, nhưng range
hàm không phải là trình tạo trước Python 3.0, và do đó, cấu trúc tôi đã sử dụng là một danh sách hiểu.
Nếu tôi muốn tạo một trình tạo hoạt động tương tự, tôi có thể làm như sau:
>>> (x**2 for x in xrange(1,11))
<generator object at 0x7f0a79273488>
Tuy nhiên, trong Python 3, range
là một trình tạo, vì vậy kết quả chỉ phụ thuộc vào cú pháp bạn sử dụng (dấu ngoặc vuông hoặc dấu ngoặc tròn).
Hiểu máy phát điện là một cách dễ dàng để tạo máy phát điện với một cấu trúc nhất định. Giả sử bạn muốn một generator
kết quả đầu ra lần lượt tất cả các số chẵn trong your_list
. Nếu bạn tạo nó bằng cách sử dụng kiểu hàm, nó sẽ như thế này:
def allEvens( L ):
for number in L:
if number % 2 is 0:
yield number
evens = allEvens( yourList )
Bạn có thể đạt được kết quả tương tự với biểu thức hiểu của trình tạo này:
evens = ( number for number in your_list if number % 2 == 0 )
Trong cả hai trường hợp, khi bạn gọi, next(evens)
bạn sẽ nhận được số chẵn tiếp theo your_list
.
Khả năng hiểu của trình tạo là một cách tiếp cận để tạo các tệp lặp, giống như một con trỏ di chuyển trên một tài nguyên. Nếu bạn biết con trỏ mysql hoặc con trỏ mongodb, bạn có thể biết rằng toàn bộ dữ liệu thực tế không bao giờ được tải vào bộ nhớ cùng một lúc mà từng lần một. Con trỏ của bạn di chuyển qua lại, nhưng luôn có một phần tử hàng / danh sách trong bộ nhớ.
Nói tóm lại, bằng cách sử dụng trình phát sinh, bạn có thể dễ dàng tạo con trỏ trong python.
Một ví dụ khác về khả năng hiểu của Generator:
print 'Generator comprehensions'
def sq_num(n):
for num in (x**2 for x in range(n)):
yield num
for x in sq_num(10):
print x