热搜: 活动 交友 discuz
查看: 1838|回复: 0

python:Iterators and Iterables

发表于 2018-10-21 09:07:16 | 显示全部楼层 |阅读模式
The Python forums and other question-and-answer websites like Quora and Stackoverflow are full of questions concerning 'iterators' and 'iterable'. Some want to know how they are defined and others want to know if there is an easy way to check, if an object is an iterator or an iterable. We will provide further down a function for this purpose.
We have seen that we can loop or iterate over various Python objects like lists, tuples and strings for example.
  1. for city in ["Berlin", "Vienna", "Zurich"]:
  2.     print(city)
  3. for city in ("Python", "Perl", "Ruby"):
  4.     print(city)
  5. for char in "Iteration is easy":
  6.     print(char)

  7. Berlin
  8. Vienna
  9. Zurich
  10. Python
  11. Perl
  12. Ruby
  13. I
  14. t
  15. e
  16. r
  17. a
  18. t
  19. i
  20. o
  21. n

  22. i
  23. s

  24. e
  25. a
  26. s
  27. y

This form of looping can be seen as iteration. Iteration is not restricted to explicit for loops. If you call the function sum, - e.g. on a list of integer values, - you do iteration as well.
So what is the difference between an iterable and an iterator?
In one perspective they are the same: You can iterate with a for loop over iterators and iterables. Every iterator is also an iterable, but not every iterable is an iterator. E.g. a list is iterable but a list is not an iterator!An iterator can be created from an iterable by using the function 'iter'.To make this possible the class of an object needs either a method '__iter__', which returns an iterator, or a '__getitem__' method with sequential indexes starting with 0.
Iterators are objects with a '__next__' method, which will be used when the function 'next' is called.
So what is going on behind the scenes, when a for loop is executed? The for statement calls iter() on the object ( which should be a so-called container object), which it is supposed to loop over. If this call is successful, the iter call will return return an iterator object that defines the method __next__() which accesses elements of the object one at a time. The  __next__() method will raise a StopIteration exception, if there are no further elements available. The for loop whill terminate as soon as it catches a StopIteration exception. You can call the __next__() method using the next() built-in function. This is how it works:
  1. cities = ["Berlin", "Vienna", "Zurich"]
  2. iterator_obj = iter(cities)
  3. print(iterator_obj)
  4. print(next(iterator_obj))
  5. print(next(iterator_obj))
  6. print(next(iterator_obj))

  7. <list_iterator object at 0x7f08a055e0b8>
  8. Berlin
  9. Vienna
  10. Zurich
If we called 'next(iterator_obj)' one more time, it would return 'StopIteration'
The following function 'iterable' will return True, if the object 'obj' is an iterable and False otherwise.
  1. def iterable(obj):
  2.      try:
  3.          iter(obj)
  4.          return True
  5.      except TypeError:
  6.          return False
  8. for element in [34, [4, 5], (4, 5), {"a":4}, "dfsdf", 4.5]:
  9.     print(element, "iterable: ", iterable(element))

  10. 34 iterable:  False
  11. [4, 5] iterable:  True
  12. (4, 5) iterable:  True
  13. {'a': 4} iterable:  True
  14. dfsdf iterable:  True
  15. 4.5 iterable:  False

We have described how an iterator works. So if you want to add an iterator behavior to your class, you have to add the __iter__ and the __next__ method to your class. The __iter__ method returns an iterator object. If the class contains a __next__, it is enough for the __iter__ method to return self, i.e. a reference to itself:
  1. class Reverse:
  2.     """
  3.     Creates Iterators for looping over a sequence backwards.
  4.     """
  6.     def __init__(self, data):
  7. = data
  8.         self.index = len(data)
  9.     def __iter__(self):
  10.         return self
  11.     def __next__(self):
  12.         if self.index == 0:
  13.             raise StopIteration
  14.         self.index = self.index - 1
  15.         return[self.index]
  16. lst = [34, 978, 42]
  17. lst_backwards = Reverse(lst)
  18. for el in lst_backwards:
  19.     print(el)

  20. 42
  21. 978
  22. 34


使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册


QQ|小黑屋|Archiver|手机版|Plone技术资料 ( 湘ICP备14006519号-1 )

GMT+8, 2019-11-19 00:48 , Processed in 0.066075 second(s), 16 queries , Gzip On.

Powered by Plone! X3.4

© 2001-2019

快速回复 返回顶部 返回列表