Yield python là gì

Bài viết gốc:https://manhhomienbienthuy.bitbucket.io/2016/Jan/05/python-iterator-generator.html (đã xin phnghiền người sáng tác

*
)

Trong nội dung bài viết này, chúng ta đã tìm hiểu một số tư tưởng siêu phổ biến trong Pynhỏ nhưng mà cũng thường bị làm lơ đề xuất hoàn toàn có thể dẫn tới các phát âm sai nhất mực. Những định nghĩa đó đó là iterator và generator. Chúng được áp dụng tiếp tục cho nên việc gọi nhằm thực hiện chúng cho đúng là siêu cần thiết.

Bạn đang xem: Yield python là gì

Iterator

Chúng ta hoàn toàn có thể áp dụng vòng lặp for để phê chuẩn qua những phần tử của một list:

Có một trong những hàm dựng sẵn bao gồm Pythanh mảnh được cho phép thao tác làm việc với hầu hết đối tượng người sử dụng này:

Giao thức interation

Những đối tượng người tiêu dùng "iterable" hoàn toàn có thể được xem xét qua những phần tử, cũng chính vì bọn chúng được thiết lập cách làm __iter__. Pmùi hương thức này đã trả về một đối tượng người tiêu dùng iterator. Đối tượng này rất cần được hỗ trợ giao thức iteration (sẽ được kể đến sau). Nếu một đối tượng "iterable" có rất nhiều kiểu chuẩn y bộ phận khác biệt, rất có thể họ sẽ nên thêm những xử lý nhằm xác định iterator. (lấy một ví dụ một đồ vật thị rất có thể trông nom theo hướng rộng lớn với theo chiều sâu.)

Với đối tượng người dùng iterator, nó rất cần được được cài đặt nhị thủ tục sau, và bộ nhị cách tiến hành này được hotline là giao thức iteration.

Pmùi hương thức __iter__ trả về thiết yếu đối tượng người sử dụng iterator. Phương thơm thức này được kinh nghiệm setup cho tất cả đối tượng người dùng "iterable" và iterator để rất có thể thực hiện các câu lệnh for cùng in.Pmùi hương thức __next__ (ngơi nghỉ Pykhông lớn 2 là next) trả về thành phần tiếp theo sau. Nếu không hề thành phần nào nữa thì StopIteration exception sẽ tiến hành raise.

Một hàm dựng sẵn của Python là iter dìm nguồn vào là một trong đối tượng "iterable" với trả về công dụng là một iterator.

Chúng ta hoàn toàn có thể tự thiết lập iterator là một class. Ví dụ bên dưới đấy là một iterator hoạt động tựa như như hàm range tất cả sẵn của Pyhạn hẹp.

class yrange: def __init__(self, n): self.i = 0 self.n = n def __iter__(self): return self def __next__(self): if self.i Phương thơm thức __iter__ đang làm đối tượng người dùng biến đổi đối tượng người tiêu dùng "iterable". Về bản chất, hàm iter vẫn Hotline đến phương thức __iter__ này của mỗi đối tượng.

Giá trị trả về của __iter__ là 1 trong những iterator. Nó cần phải có thủ tục __next__ cùng phải trả về StopIteration nếu như không còn phần demo làm sao nữa.

Hãy thử cùng với ví dụ trên:

class zrange: def __init__(self, n): self.n = n def __iter__(self): return zrange_iter(self.n)class zrange_iter: def __init__(self, n): self.i = 0 self.n = n def __iter__(self):# Iterators are iterables too# Adding this functions to lớn make them so return self def __next__(self): if self.i Iterator của Pyeo hẹp gồm một Đặc điểm là nó chỉ rất có thể được coi xét qua một lần. Nên giả dụ đã lưu ý qua thành phần như thế nào rồi thì chúng ta cần thiết duyệt y qua nó thêm lần nào nữa.

Vì Điểm sáng trên, cần trường hợp iterator cùng đối tượng "iterable" là 1, thì nó cũng chỉ có thể tiến hành iteration một lần. Nhưng ví như chúng chưa phải là một trong những, thì chúng ta có thể triển khai từng nào lần tùy ý.

def yrange(n): i = 0 while i Mỗi lần lệnh yield được chạy, nó sẽ hình thành một quý hiếm new. (Vì thế nó mới được Gọi là generator)

Từ generator được sử dụng cho tất cả hàm (hàm generator là hàm đã nói sinh hoạt trên) với kết quả mà lại hàm kia có mặt (đối tượng người dùng được hàm generator sinh ra cũng rất được gọi là generator). Vì vậy thỉnh thoảng vấn đề này tạo khó khăn đọc một ít.

Vậy một generator hoạt động như thế nào? lúc hàm generator được Call, nó trả tác dụng là 1 trong những đối tượng generator với không thực sự Điện thoại tư vấn cùng tiến hành hàm. lúc cách làm __next__ được điện thoại tư vấn, hàm generator đang bắt đầu chạy, cho đến lúc nó gặp mặt lệnh yield. Giá trị được yield sẽ được trả về cho hàm __next__.

lấy ví dụ như dưới đây minch họa quá trình liên can thân yield cùng __next__ trong một đối tượng người sử dụng generator.

def integers(): """Infinite sequence of integers.""" i = 1 while True: yield i i = i + 1def squares(): for i in integers(): yield i * idef take(n, seq): """Returns first n values from the given sequence.""" seq = iter(seq) result = <> try: for i in range(n): result.append(seq.__next__()) except StopIteration: pass return resultprint(take(5, squares()))# prints <1, 4, 9, 16, 25>Biểu thức generatorBiểu thức generator là 1 vươn lên là thể của các mục comprehension. Nó trông cực kỳ kiểu như các mục comprehension nhưng mà nó trả về một generator nỗ lực vì chưng một menu.

Đơn giản hóa code

Đơn giản hóa code là một trong tác dụng của hàm với biểu thức generator. Để minc họa mang lại bài toán này, chúng ta sẽ đem một ví dụ ví dụ.

Chúng ta đã so sánh vấn đề thiết lập hàm firstn (hàm trả về n số ngulặng ko âm đầu tiên) với n hoàn toàn có thể rất to lớn cùng mang sử rằng mỗi số đề xuất một lượng bộ nhớ tương đối những.

Đầu tiên, một bí quyết làm cho thường thì đó là thực hiện list:

def firstn(n): num, nums = 0, <> while num n: nums.append(num) num += 1 return numssum_of_first_n = sum(firstn(1000000))Đoạn code bên trên dễ dàng cùng dễ hiểu. Tất nhiên là nó hoạt động giỏi, không tính một sự việc nhỏ dại là nó giữ tổng thể list vào bộ nhớ lưu trữ. Trong nhiều phần những trường vừa lòng, điều này là ko tuyệt Khi yêu cầu thực hiện mang lại dung lượng bộ nhớ lưu trữ mập mang lại vậy.

Xem thêm: Nghĩa Của Từ Paragliding Là Gì, Paragliding Là Gì, Nghĩa Của Từ Paragliding

Bây tiếng, bọn họ thử áp dụng iterator. Dưới đấy là một thiết đặt cho việc này.

class firstn(object): def __init__(self, n): self.n = n self.num, self.nums = 0, <> def __iter__(self): return self def __next__(self): if self.num self.n: cur, self.num = self.num, self.num + 1 return cur else: raise StopIteration()sum_of_first_n = sum(firstn(1000000))Đoạn code trên đã chuyển động nhỏng họ mong ước, nhưng nó bao gồm một trong những vụ việc như:

Có các mẫu dựng sẵn được sử dụngLogic được biểu hiện một bí quyết phức tạpCode bắt đầu vượt lâu năm chỉ nhằm thành lập một iterator

Chúng ta có thể áp dụng generator để tạo iterator nlắp gọn gàng rộng. Chúng ta rất có thể cài đặt nhỏng sau:

def firstn(n): num = 0 while num n: yield num num += 1sum_of_first_n = sum(firstn(1000000))Hàm firstn sinh hoạt trên chỉ là 1 trong những ví dụ minh họa. Pydong dỏng có hàm dựng sẵn là range vận động tương tự như như vậy. Tất nhiên là thực tế chúng ta buộc phải sử dụng hàm dựng sẵn này.

Nâng cao hiệu suất

Việc sử dụng generator có thể nâng cao hiệu suất chính vì generator chỉ thực sự sinc tác dụng khi được Điện thoại tư vấn. Do kia, nó vẫn áp dụng ít bộ lưu trữ hơn. Dường như, chúng ta không cần phải ngóng toàn bộ các phần tử của chính nó được hiện ra hết mới hoàn toàn có thể thực hiện. Chúng sẽ tiến hành sinh trong quy trình bọn họ Hotline generator. Đây là đều tác dụng có được Khi chúng ta áp dụng iterator, nhưng generator là biện pháp nđính thêm gọn để tạo nên một iterator.

Để minch họa, họ vẫn so sánh nhì hàm dựng sẵn của Pythanh mảnh 2 là range với xrange.

Cả range cùng xrange đa số bộc lộ một khoảng các số ngulặng. Tuy nhiên, range trả về một danh mục còn xrange trả về một generator.

Bây giờ đồng hồ, họ và tính tổng của 1 triệu số nguim ko âm thứ nhất.

# using non-generatorsum_of_first_n = sum(range(1000000))# using generatorsum_of_first_n = sum(xrange(1000000))Hai loại code trông hơi tương đương nhau. Tuy nhiên vấn đề sử dụng range tốn bộ nhớ lưu trữ và thời hạn hơn.

Khi họ áp dụng range, nó sẽ xây dựng dựng menu 1 triệu phần tử cùng kế tiếp tính tổng của bọn chúng. Việc này khôn cùng tiêu tốn lãng phí bộ lưu trữ vì chưng bọn họ chỉ việc tính tổng của bọn chúng mà thôi. Sự tiêu tốn lãng phí càng tăng thêm lúc con số thành phần tạo thêm và form size mỗi phần tử cũng to hơn.

Vì số đông ích lợi của generator mà lại trong Pythuôn 3, hàm range chuyển động giống như cùng với xrange của Pyhạn hẹp 2, tức là nó sẽ trả về generator chđọng không hẳn là các mục.

Lưu ý điểm sáng của iterator là nó chỉ chu đáo qua một lần, nên việc áp dụng generator đang đem về hiệu quả giả dụ bọn họ ko mong muốn chu đáo nó nhiều hơn nữa 1 lần.

Hãy chu đáo ví dụ sau:

a = sum(xrange(1000000))p = product(xrange(1000000))Giả sử rằng việc sinh một vài rất tốn thời hạn và bộ nhớ, thì vào ví dụ trên, bọn họ đã tiến hành công việc tốn kỉm này gấp đôi. Trong trường phù hợp này, bài toán áp dụng menu cùng lưu sẵn trong bộ lưu trữ có vẻ như hiệu quả rộng.

nums = list(xrange(1000000))a = sum(nums)p = product(nums)Vì vậy việc chắt lọc áp dụng generator hay là không dựa vào nhiều vào thực tế những hiểu biết của các bước. Nên các bạn hãy Để ý đến và tuyển lựa cẩn thận.

Itertools

Module itertools là thỏng viện chuẩn chỉnh của Pythuôn. Nó cung cấp mang lại chúng ta không hề ít cơ chế để gia công Việc với các iterator.

Trong nội dung bài viết này, họ đang điểm qua một vài hàm thú vị.

Xem thêm: Cách Trả Giá Shopee Ở Đâu - Cách Trả Giá Trên Shopee Nhanh Và Hiệu Quả Nhất!

chain sẽ gộp các iterator với nhau sản xuất thành một iterator.


Chuyên mục: Hỏi Đáp