Iterator là các đối tượng cho phép ta lấy từng phần tử của nó, hành động này có thể được lặp đi lặp lại. Trong bài viết này, Tin học của em sẽ cùng bạn sẽ tìm hiểu cách iterator hoạt động trong Python và cách bạn có thể xây dựng trình lặp của riêng mình bằng các phương thức __iter__ và __next__.

Iterator trong Python là gì?

Iterator ở khắp mọi nơi trong Python, bên trong các vòng lặp, comprehension, generator…

Nó đơn giản chỉ là các đối tượng cho phép ta lấy từng phần tử, bất cứ khi nào bạn sử dụng vòng lặp hay các kĩ thuật để có được giá trị một nhóm phần tử ở một thời điểm nào đó.

Về mặt kỹ thuật, Iterator trong Python phải thực hiện hai phương thức đặc biệt là __iter__() và __next__(), gọi chung là giao thức iterator (Iterator Protocol)

  • Phương thức __iter__ trả về chính đối tượng iterator. Phương thức này được yêu cầu cài đặt cho cả đối tượng “iterable” và iterator để có thể sử dụng các câu lệnh for và in.
  • Phương thức __next__ trả về phần tử tiếp theo. Nếu không còn phần tử nào nữa thì sẽ có lỗi StopIteration xảy ra.

Iterable object là một đối tượng sau khi sử dụng các phương thức sẽ trả về một iterator, ví dụ như Chuỗi, List, Tuple.

Iter() là một hàm dựng sẵn trong Python nhận đầu vào là một đối tượng iterable và trả về kết quả là một iterator.

# Khai bao mot list my_list = [4, 7, 0, 3]   # lay mot iterator bang cach su dung iter() my_iter = iter(my_list)   ## su dung next()   #prints 4 print(next(my_iter))   #prints 7 print(next(my_iter))   ## next(obj) chinh la obj.__next__()   #prints 0 print(my_iter.__next__())   #prints 3 print(my_iter.__next__())   ## Xay ra loi StopIteration vi het gia tri tra ve next(my_iter)

Chạy chương trình, kết quả trả về là:

4 7 0 3   Traceback (most recent call last): File "<stdin>", line 24, in <module> next(my_iter) StopIteration

Một cách tương tự trả về kết quả này là ta sử dụng vòng lặp for.

>>> for element in my_list: ... print(element) ... 4 7 0 3

Cách vòng lặp hoạt động

Như chúng ta thấy trong ví dụ trên, vòng lặp for có thể lặp lại tự động thông qua việc sử dụng danh sách.

Trong thực tế, vòng lặp for có thể lặp lại trên bất kỳ iterable nào. Chúng ta hãy xem kỹ hơn về cách vòng lặp for được thực hiện trong Python.

for element in iterable: # do something with element

Được thực hiện tương tự như:

# iter_obj là một iterator object tạo từ iterable iter_obj = iter(iterable)   # vòng lặp while True:      try:         # sử dụng next         element = next(iter_obj)      except StopIteration:         # nếu xảy ra lỗi StopIteration thì vòng lặp sẽ được break ra ngoài         break

Ở ví dụ này, bên trong vòng lặp for ta tạo một iterator object tên là iter_obj bằng cách gọi iter() trên iterable.

Và như bạn thấy thì vòng lặp for ở đây chính là vòng lặp while vô hạn. Next() bên trong vòng lặp lấy ra các phần tử để thực hiện các câu lệnh ở for loop. Đến khi lấy hết các giá trị thì ngoại lệ StopIteration sẽ được sinh ra và vòng lặp kết thúc.

Xây dựng trình vòng lặp Iterator trong Python

Chúng ta có thể tự xây dựng iterator là một class. Xây dựng Iterator rất dễ dàng trong Python, chúng ta chỉ cần thực hiện các phương thức __iter__() và __next__().

class PowTwo:        def __init__(self, max = 0):         self.max = max        def __iter__(self):         self.n = 0         return self        def __next__(self):         if self.n <= self.max:           result = 2 ** self.n           self.n += 1           return result      else: raise StopIteration

Phương thức __iter__ sẽ làm đối tượng trở thành đối tượng iterable.

Giá trị trả về của __iter__ là một iterator. Nó cần có phương thức __next__ và trả về StopIteration nếu không còn phần thử nào nữa.

Tạo ra một iterator và chạy chương trình như sau:

>>> a = PowTwo(4) >>> i = iter(a) >>> next(i) 1 >>> next(i) 2 >>> next(i) 4 >>> next(i) 8 >>> next(i) 16 >>> next(i) Traceback (most recent call last): ... StopIteration

Chúng ta cũng có thể sử dụng một vòng lặp for để lặp iterator

>>> for i in PowTwo(5): ... print(i) ... 1 2 4 8 16 32

Iterator lặp vô hạn trong Python

Không phải tất cả các đối tượng iterator đều sẽ được gọi hết các phần tử và kết thúc khi không còn phần tử. Có một số trường hợp iterator sẽ lặp vô hạn. Ví dụ như sau:

>>> int() 0 >>> inf = iter(int,1) >>> next(inf) 0 >>> next(inf) 0

Chúng ta có thể thấy rằng hàm int() luôn trả về 0. Vì vậy, việc truyền nó dưới dạng iter(int, 1) sẽ trả về một iterator lặp cho đến khi giá trị trả về bằng 1. Điều này không bao giờ xảy ra và đây chính là iterator lặp vô hạn. Bạn cần chú ý khi xử lý trong các trường hợp thế này.

Ngoài ra, bạn cũng có thể tự xây dựng iterator lặp vô hạn. Ví dụ sau đây sẽ lặp vô hạn và trả về các số lẻ vì không có điều kiện dừng nào cả.

class InfIter:      def __iter__(self):         self.num = 1         return self      def __next__(self):         num = self.num         self.num += 2         return num

Chạy chương trình:

>>> a = iter(InfIter()) >>> next(a) 1 >>> next(a) 3 >>> next(a) 5 >>> next(a) 7

Ưu điểm của việc sử dụng Iterator lặp là chúng tiết kiệm tài nguyên. Giống như hiển thị ở trên, bạn có thể nhận được tất cả các số lẻ mà không lưu trữ trên toàn bộ hệ thống số ở bộ nhớ.

340 BÌNH LUẬN

  1. This particular blog is really educating and besides informative. I have picked up a lot of interesting tips out of this source. I ad love to visit it every once in a while. Cheers!

  2. Wow! This can be one particular of the most beneficial blogs We have ever arrive across on this subject. Basically Great. I am also a specialist in this topic so I can understand your hard work.

  3. Wonderful paintings! This is the type of info that should be shared across the web. Shame on Google for no longer positioning this post higher! Come on over and consult with my site. Thank you =)

  4. Wow! This can be one particular of the most useful blogs We ave ever arrive across on this subject. Actually Magnificent. I am also an expert in this topic therefore I can understand your hard work.

  5. It’а†s actually a nice and helpful piece of info. I am satisfied that you simply shared this useful information with us. Please stay us up to date like this. Thank you for sharing.

  6. It as not that I want to duplicate your web site, but I really like the design. Could you tell me which style are you using? Or was it especially designed?

  7. This very blog is obviously awesome and also informative. I have chosen a lot of interesting things out of this amazing blog. I ad love to return over and over again. Thanks a bunch!

  8. I thought it was going to be some boring old post, but it really compensated for my time. I will post a link to this page on my blog. I am sure my visitors will find that very useful.

  9. I think other web site proprietors should take this web site as an model, very clean and excellent user friendly style and design, let alone the content. You are an expert in this topic!

  10. Usually I do not read article on blogs, but I would like to say that this write-up very pressured me to take a look at and do so! Your writing taste has been surprised me. Thanks, quite great article.

  11. It’а†s really a nice and helpful piece of info. I’а†m glad that you just shared this helpful information with us. Please keep us up to date like this. Thank you for sharing.

  12. Pretty nice post. I just stumbled upon your weblog and wished to say that I ave really enjoyed browsing your blog posts. In any case I all be subscribing to your feed and I hope you write again soon!

  13. I used to be suggested this blog via my cousin. I am no longer sure whether this post is written by him as no one else realize such detailed about my trouble. You are wonderful! Thanks!

  14. Attractive part of content. I simply stumbled upon your site and in accession capital to assert that I acquire in fact loved account your weblog posts.

    Anyway I’ll be subscribing on your feeds or even I success
    you get entry to persistently quickly.

  15. I have to thank you for the efforts you have put in writing this blog.

    I’m hoping to see the same high-grade content from you later on as well.
    In truth, your creative writing abilities has encouraged me to get my own, personal
    blog now 😉

  16. Normally I do not learn article on blogs, however I would like to say that this write-up very compelled me to try and do so! Your writing taste has been amazed me. Thank you, quite great article.

  17. Hello! This post could not be written any better!
    Reading this post reminds me of my previous room mate!

    He always kept talking about this. I will forward this write-up to him.
    Fairly certain he will have a good read. Thank you for sharing!

  18. You could certainly see your expertise in the work you write. The world hopes for more passionate writers like you who aren at afraid to mention how they believe. All the time follow your heart.

  19. you are really a good webmaster. The site loading speed is amazing. It seems that you are doing any unique trick. Also, The contents are masterpiece. you have done a magnificent job on this topic!

  20. Hello There. I found your blog using msn. This is a really well written article.
    I’ll be sure to bookmark it and return to read more of your useful
    information. Thanks for the post. I will certainly comeback.

  21. Amazing blog! Do you have any helpful hints for aspiring writers?
    I’m hoping to start my own blog soon but I’m a little lost on everything.
    Would you suggest starting with a free platform like WordPress or go for a paid option? There are so many options
    out there that I’m totally overwhelmed .. Any suggestions?

    Thanks a lot!

  22. Outstanding post however I was wondering if you could write a litte more on this subject? I ad be very grateful if you could elaborate a little bit more. Appreciate it!

  23. This is the right site for anyone who would like to find out about this topic.
    You know so much its almost hard to argue with you
    (not that I personally would want to…HaHa).
    You certainly put a new spin on a subject that’s been written about for a long time.

    Wonderful stuff, just wonderful!

  24. Wow! This can be one particular of the most useful blogs We ave ever arrive across on this subject. Actually Wonderful. I am also an expert in this topic therefore I can understand your hard work.

  25. You could definitely see your enthusiasm in the work you write. The world hopes for more passionate writers like you who are not afraid to say how they believe. Always go after your heart.

  26. Thanks a lot for sharing this with all of us you actually know what you are talking about! Bookmarked. Please also visit my website =). We could have a link exchange contract between us!

  27. It’а†s in point of fact a great and helpful piece of information. I’а†m glad that you simply shared this helpful information with us. Please keep us up to date like this. Thanks for sharing.

  28. Wow, incredible blog structure! How lengthy have you been running a blog for? you made blogging glance easy. The full glance of your site is great, let alone the content!

  29. Your style is really unique compared to other folks I ave read stuff from. Many thanks for posting when you have the opportunity, Guess I will just bookmark this blog.

  30. It’а†s really a nice and helpful piece of information. I’а†m satisfied that you shared this helpful info with us. Please stay us up to date like this. Thank you for sharing.

  31. You can certainly see your skills in the work you write. The sector hopes for even more passionate writers like you who are not afraid to say how they believe. At all times go after your heart.

  32. Keep up the great work , I read few content on this site and I believe that your site is very interesting and contains sets of fantastic information.

  33. That is a really good tip particularly to those fresh to the blogosphere. Brief but very precise info Appreciate your sharing this one. A must read article!

  34. Very nice post. I just stumbled upon your blog and wanted to say that I have truly enjoyed browsing your blog posts. In any case I all be subscribing to your feed and I hope you write again very soon!

  35. Usually I do not learn post on blogs, however I wish to say that this write-up very forced me to try and do it! Your writing style has been surprised me. Thanks, quite nice post.

THOÁT KHỎI BÌNH LUẬN

Please enter your comment!
Please enter your name here