<p>How would one create an iterative function (or iterator object) in python?</p>

[{'answer_id': 19152, 'author': 'akdom', 'author_id': 145, 'author_profile': 'https://Stackoverflow.com/users/145', 'pm_score': 7, 'selected': False, 'text': '<p>First of all the <a href="https://docs.python.org/3/library/itertools.html" rel="noreferrer">itertools module</a> is incredibly useful for all sorts of cases in which an iterator would be useful, but here is all you need to create an iterator in python:</p>\n\n<blockquote>\n  <p>yield</p>\n</blockquote>\n\n<p>Isn\'t that cool?  Yield can be used to replace a normal <strong>return</strong> in a function.  It returns the object just the same, but instead of destroying state and exiting, it saves state for when you want to execute the next iteration.  Here is an example of it in action pulled directly from the <a href="http://docs.python.org/lib/itertools-functions.html" rel="noreferrer">itertools function list</a>:</p>\n\n<pre><code>def count(n=0):\n    while True:\n        yield n\n        n += 1\n</code></pre>\n\n<p>As stated in the functions description (it\'s the <strong>count()</strong> function from the itertools module...) , it produces an iterator that returns consecutive integers starting with n.</p>\n\n<p><a href="https://docs.python.org/2/reference/expressions.html#generator-expressions" rel="noreferrer">Generator expressions</a> are a whole other can of worms (awesome worms!).  They may be used in place of a <a href="http://www.secnetix.de/olli/Python/list_comprehensions.hawk" rel="noreferrer">List Comprehension</a> to save memory (list comprehensions create a list in memory that is destroyed after use if not assigned to a variable, but generator expressions can create a Generator Object... which is a fancy way of saying Iterator). Here is an example of a generator expression definition:</p>\n\n<pre><code>gen = (n for n in xrange(0,11))\n</code></pre>\n\n<p>This is very similar to our iterator definition above except the full range is predetermined to be between 0 and 10.</p>\n\n<p>I just found <strong>xrange()</strong> (suprised I hadn\'t seen it before...) and added it to the above example.  <strong>xrange()</strong> is an iterable version of <strong>range()</strong> which has the advantage of not prebuilding the list.  It would be  very useful if you had a giant corpus of data to iterate over and only had so much memory to do it in.</p>\n'}, {'answer_id': 24377, 'author': 'ars', 'author_id': 2611, 'author_profile': 'https://Stackoverflow.com/users/2611', 'pm_score': 11, 'selected': True, 'text': '<p>Iterator objects in python conform to the iterator protocol, which basically means they provide two methods: <code>__iter__()</code>  and  <code>__next__()</code>.  </p>\n\n<ul>\n<li><p>The <code>__iter__</code> returns the iterator object and is implicitly called\nat the start of loops.</p></li>\n<li><p>The <code>__next__()</code> method returns the next value and is implicitly called at each loop increment.  This method raises a StopIteration exception when there are no more value to return, which is implicitly captured by looping constructs to stop iterating.</p></li>\n</ul>\n\n<p>Here\'s a simple example of a counter:</p>\n\n<pre><code>class Counter:\n    def __init__(self, low, high):\n        self.current = low - 1\n        self.high = high\n\n    def __iter__(self):\n        return self\n\n    def __next__(self): # Python 2: def next(self)\n        self.current += 1\n        if self.current &lt; self.high:\n            return self.current\n        raise StopIteration\n\n\nfor c in Counter(3, 9):\n    print(c)\n</code></pre>\n\n<p>This will print:</p>\n\n<pre><code>3\n4\n5\n6\n7\n8\n</code></pre>\n\n<p>This is easier to write using a generator, as covered in a previous answer:</p>\n\n<pre><code>def counter(low, high):\n    current = low\n    while current &lt; high:\n        yield current\n        current += 1\n\nfor c in counter(3, 9):\n    print(c)\n</code></pre>\n\n<p>The printed output will be the same.  Under the hood, the generator object supports the iterator protocol and does something roughly similar to the class Counter.</p>\n\n<p>David Mertz\'s article, <a href="https://www.ibm.com/developerworks/library/l-pycon/" rel="noreferrer">Iterators and Simple Generators</a>, is a pretty good introduction. </p>\n'}, {'answer_id': 7542261, 'author': 'Ethan Furman', 'author_id': 208880, 'author_profile': 'https://Stackoverflow.com/users/208880', 'pm_score': 9, 'selected': False, 'text': '<p>There are four ways to build an iterative function:</p>\n\n<ul>\n<li>create a generator (uses the <a href="http://docs.python.org/py3k/reference/expressions.html#yield-expressions" rel="noreferrer">yield keyword</a>)</li>\n<li>use a generator expression (<a href="http://docs.python.org/py3k/reference/expressions.html#generator-expressions" rel="noreferrer">genexp</a>)</li>\n<li>create an iterator (defines <a href="http://docs.python.org/py3k/library/stdtypes.html?highlight=__iter__#iterator-types" rel="noreferrer"><code>__iter__</code> and <code>__next__</code></a> (or <code>next</code> in Python 2.x))</li>\n<li>create a class that Python can iterate over on its own (<a href="http://docs.python.org/py3k/reference/datamodel.html?highlight=__getitem__#object.__getitem__" rel="noreferrer">defines <code>__getitem__</code></a>)</li>\n</ul>\n\n<p>Examples:</p>\n\n<pre><code># generator\ndef uc_gen(text):\n    for char in text.upper():\n        yield char\n\n# generator expression\ndef uc_genexp(text):\n    return (char for char in text.upper())\n\n# iterator protocol\nclass uc_iter():\n    def __init__(self, text):\n        self.text = text.upper()\n        self.index = 0\n    def __iter__(self):\n        return self\n    def __next__(self):\n        try:\n            result = self.text[self.index]\n        except IndexError:\n            raise StopIteration\n        self.index += 1\n        return result\n\n# getitem method\nclass uc_getitem():\n    def __init__(self, text):\n        self.text = text.upper()\n    def __getitem__(self, index):\n        return self.text[index]\n</code></pre>\n\n<p>To see all four methods in action:</p>\n\n<pre><code>for iterator in uc_gen, uc_genexp, uc_iter, uc_getitem:\n    for ch in iterator(\'abcde\'):\n        print(ch, end=\' \')\n    print()\n</code></pre>\n\n<p>Which results in:</p>\n\n<pre><code>A B C D E\nA B C D E\nA B C D E\nA B C D E\n</code></pre>\n\n<p><strong>Note</strong>:</p>\n\n<p>The two generator types (<code>uc_gen</code> and <code>uc_genexp</code>) cannot be <code>reversed()</code>; the plain iterator (<code>uc_iter</code>) would need the <code>__reversed__</code> magic method (which, <a href="https://docs.python.org/3/reference/datamodel.html#object.__reversed__" rel="noreferrer">according to the docs</a>, must return a new iterator, but returning <code>self</code> works (at least in CPython)); and the getitem iteratable (<code>uc_getitem</code>) must have the <code>__len__</code> magic method:</p>\n\n<pre><code>    # for uc_iter we add __reversed__ and update __next__\n    def __reversed__(self):\n        self.index = -1\n        return self\n    def __next__(self):\n        try:\n            result = self.text[self.index]\n        except IndexError:\n            raise StopIteration\n        self.index += -1 if self.index &lt; 0 else +1\n        return result\n\n    # for uc_getitem\n    def __len__(self)\n        return len(self.text)\n</code></pre>\n\n<hr>\n\n<p>To answer Colonel Panic\'s secondary question about an infinite lazily evaluated iterator, here are those examples, using each of the four methods above:</p>\n\n<pre><code># generator\ndef even_gen():\n    result = 0\n    while True:\n        yield result\n        result += 2\n\n\n# generator expression\ndef even_genexp():\n    return (num for num in even_gen())  # or even_iter or even_getitem\n                                        # not much value under these circumstances\n\n# iterator protocol\nclass even_iter():\n    def __init__(self):\n        self.value = 0\n    def __iter__(self):\n        return self\n    def __next__(self):\n        next_value = self.value\n        self.value += 2\n        return next_value\n\n# getitem method\nclass even_getitem():\n    def __getitem__(self, index):\n        return index * 2\n\nimport random\nfor iterator in even_gen, even_genexp, even_iter, even_getitem:\n    limit = random.randint(15, 30)\n    count = 0\n    for even in iterator():\n        print even,\n        count += 1\n        if count &gt;= limit:\n            break\n    print\n</code></pre>\n\n<p>Which results in (at least for my sample run):</p>\n\n<pre><code>0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40 42 44 46 48 50 52 54\n0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38\n0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30\n0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32\n</code></pre>\n\n<hr>\n\n<p>How to choose which one to use?  This is mostly a matter of taste.  The two methods I see most often are generators and the iterator protocol, as well as a hybrid (<code>__iter__</code> returning a generator).</p>\n\n<p>Generator expressions are useful for replacing list comprehensions (they are lazy and so can save on resources).</p>\n\n<p>If one needs compatibility with earlier Python 2.x versions use <code>__getitem__</code>.</p>\n'}, {'answer_id': 11690539, 'author': 'Manux', 'author_id': 319926, 'author_profile': 'https://Stackoverflow.com/users/319926', 'pm_score': 7, 'selected': False, 'text': '<p>I see some of you doing <code>return self</code> in <code>__iter__</code>. I just wanted to note that <code>__iter__</code> itself can be a generator (thus removing the need for <code>__next__</code> and raising <code>StopIteration</code> exceptions)</p>\n\n<pre><code>class range:\n  def __init__(self,a,b):\n    self.a = a\n    self.b = b\n  def __iter__(self):\n    i = self.a\n    while i &lt; self.b:\n      yield i\n      i+=1\n</code></pre>\n\n<p>Of course here one might as well directly make a generator, but for more complex classes it can be useful.</p>\n'}, {'answer_id': 35779493, 'author': 'Nizam Mohamed', 'author_id': 4522780, 'author_profile': 'https://Stackoverflow.com/users/4522780', 'pm_score': 2, 'selected': False, 'text': "<p>This is an iterable function without <code>yield</code>. It make use of the <code>iter</code> function and a closure which keeps it's state in a mutable (<code>list</code>) in the enclosing scope for python 2.  </p>\n\n<pre><code>def count(low, high):\n    counter = [0]\n    def tmp():\n        val = low + counter[0]\n        if val &lt; high:\n            counter[0] += 1\n            return val\n        return None\n    return iter(tmp, None)\n</code></pre>\n\n<p>For Python 3, closure state is kept in an immutable in the enclosing scope and <code>nonlocal</code> is used in local scope to update the state variable.  </p>\n\n<pre><code>def count(low, high):\n    counter = 0\n    def tmp():\n        nonlocal counter\n        val = low + counter\n        if val &lt; high:\n            counter += 1\n            return val\n        return None\n    return iter(tmp, None)  \n</code></pre>\n\n<p>Test;</p>\n\n<pre><code>for i in count(1,10):\n    print(i)\n1\n2\n3\n4\n5\n6\n7\n8\n9\n</code></pre>\n"}, {'answer_id': 36138037, 'author': 'aq2', 'author_id': 5806943, 'author_profile': 'https://Stackoverflow.com/users/5806943', 'pm_score': 4, 'selected': False, 'text': '<p>This question is about iterable objects, not about iterators. In Python, sequences are iterable too so one way to make an iterable class is to  make it behave like a sequence, i.e. give it <code>__getitem__</code> and <code>__len__</code> methods. I have tested this on Python 2 and 3.</p>\n\n<pre><code>class CustomRange:\n\n    def __init__(self, low, high):\n        self.low = low\n        self.high = high\n\n    def __getitem__(self, item):\n        if item &gt;= len(self):\n            raise IndexError("CustomRange index out of range")\n        return self.low + item\n\n    def __len__(self):\n        return self.high - self.low\n\n\ncr = CustomRange(0, 10)\nfor i in cr:\n    print(i)\n</code></pre>\n'}, {'answer_id': 50038486, 'author': 'Daniil Mashkin', 'author_id': 2207154, 'author_profile': 'https://Stackoverflow.com/users/2207154', 'pm_score': 3, 'selected': False, 'text': '<p>If you looking for something short and simple, maybe it will be enough for you:</p>\n\n<pre><code>class A(object):\n    def __init__(self, l):\n        self.data = l\n\n    def __iter__(self):\n        return iter(self.data)\n</code></pre>\n\n<p>example of usage:</p>\n\n<pre><code>In [3]: a = A([2,3,4])\n\nIn [4]: [i for i in a]\nOut[4]: [2, 3, 4]\n</code></pre>\n'}, {'answer_id': 51836944, 'author': 'John Strood', 'author_id': 5337834, 'author_profile': 'https://Stackoverflow.com/users/5337834', 'pm_score': 3, 'selected': False, 'text': '<p>All answers on this page are really great for a complex object. But for those containing builtin iterable types as attributes, like <code>str</code>, <code>list</code>, <code>set</code> or <code>dict</code>, or any implementation of <code>collections.Iterable</code>, you can omit certain things in your class.</p>\n\n<pre><code>class Test(object):\n    def __init__(self, string):\n        self.string = string\n\n    def __iter__(self):\n        # since your string is already iterable\n        return (ch for ch in self.string)\n        # or simply\n        return self.string.__iter__()\n        # also\n        return iter(self.string)\n</code></pre>\n\n<p>It can  be used like:</p>\n\n<pre><code>for x in Test("abcde"):\n    print(x)\n\n# prints\n# a\n# b\n# c\n# d\n# e\n</code></pre>\n'}, {'answer_id': 63337271, 'author': 'Sreevatsan', 'author_id': 13093094, 'author_profile': 'https://Stackoverflow.com/users/13093094', 'pm_score': 2, 'selected': False, 'text': "<p>Include the following code in your class code.</p>\n<pre><code> def __iter__(self):\n        for x in self.iterable:\n            yield x\n</code></pre>\n<p><strong>Make sure that you replace <code>self.iterable</code>with the iterable which you iterate through.</strong></p>\n<p><em>Here's an example code</em></p>\n<pre><code>class someClass:\n    def __init__(self,list):\n        self.list = list\n    def __iter__(self):\n        for x in self.list:\n            yield x\n\n\nvar = someClass([1,2,3,4,5])\nfor num in var: \n    print(num) \n</code></pre>\n<p>Output</p>\n<pre><code>1\n2\n3\n4\n5\n</code></pre>\n<p><strong>Note: Since strings are also iterable, they can also be used as an argument for the class</strong></p>\n<pre><code>foo = someClass(&quot;Python&quot;)\nfor x in foo:\n    print(x)\n</code></pre>\n<p>Output</p>\n<pre><code>P\ny\nt\nh\no\nn\n</code></pre>\n"}, {'answer_id': 71498451, 'author': 'Muhammad Yasirroni', 'author_id': 11671779, 'author_profile': 'https://Stackoverflow.com/users/11671779', 'pm_score': 1, 'selected': False, 'text': '<blockquote>\n<pre class="lang-py prettyprint-override"><code>class uc_iter():\n    def __init__(self):\n        self.value = 0\n    def __iter__(self):\n        return self\n    def __next__(self):\n        next_value = self.value\n        self.value += 2\n        return next_value\n</code></pre>\n</blockquote>\n<p>Improving previous <a href="https://stackoverflow.com/a/7542261/11671779">answer</a>, one of the advantage of using <code>class</code> is that you can add <code>__call__</code> to return <code>self.value</code> or even <code>next_value</code>.</p>\n<pre class="lang-py prettyprint-override"><code>class uc_iter():\n    def __init__(self):\n        self.value = 0\n    def __iter__(self):\n        return self\n    def __next__(self):\n        next_value = self.value\n        self.value += 2\n        return next_value\n    def __call__(self):\n        next_value = self.value\n        self.value += 2\n        return next_value\n</code></pre>\n<pre class="lang-py prettyprint-override"><code>c = uc_iter()\nprint([c() for _ in range(10)])\nprint([next(c) for _ in range(5)])\n# [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]\n# [20, 22, 24, 26, 28]\n</code></pre>\n<hr />\n<p>Other example of a class based on Python Random that can be both called and iterated could be seen on my implementation <a href="https://github.com/yasirroni/fakertype/blob/main/fakertype/generator.py" rel="nofollow noreferrer">here</a></p>\n'}]
['https://Stackoverflow.com/questions/19151', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/145/']