Ben Chuanlong Du's Blog

It is never too late to learn.

Generator in Python

In [2]:
sum(i for i in range(10))
Out[2]:
45
In [3]:
set(i for i in range(10))
Out[3]:
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
In [5]:
[i for i in range(10)]
Out[5]:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
In [6]:
list(i for i in range(10))
Out[6]:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
In [7]:
{i for i in range(10)}
Out[7]:
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}

Must use () to get a generator. Exception is raised without ().

In [3]:
# this is NOT tuple!!!
(i for i in range(10))
Out[3]:
<generator object <genexpr> at 0x7f2f84630938>
In [1]:
i for i in range(10)
  File "<ipython-input-1-b07d337502b5>", line 1
    i for i in range(10)
        ^
SyntaxError: invalid syntax
In [19]:
import itertools as it


def fibonacci(x1, x2):
    while True:
        yield x1
        x1, x2 = x2, x1 + x2


fiter = fibonacci(1, 1)
list(it.islice(fiter, 0, 10))
Out[19]:
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
In [23]:
fiter = fibonacci(1, 1)
list(it.takewhile(lambda x: x < 100, fiter))
Out[23]:
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]

Comment

yield cannot be used recursively. Do NOT use iterator to mimic generator as iterator is not lazy evaluation.

In [28]:
def fib2(x1, x2):
    yield x1
    return fibonacci(x2, x1 + x2)
In [29]:
fiter2 = fib2(1, 1)
list(it.islice(fiter2, 0, 10))
Out[29]:
[1]
In [34]:
import itertools as it


def fib3(x1, x2):
    it.chain([x1], fib3(x2, x1 + x2))
In [35]:
fib3(1, 1)
---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
<ipython-input-35-800beaf116b0> in <module>()
----> 1 fib3(1, 1)

<ipython-input-34-91b9f12414a5> in fib3(x1, x2)
      2 
      3 def fib3(x1, x2):
----> 4     it.chain([x1], fib3(x2, x1 + x2))

... last 1 frames repeated, from the frame below ...

<ipython-input-34-91b9f12414a5> in fib3(x1, x2)
      2 
      3 def fib3(x1, x2):
----> 4     it.chain([x1], fib3(x2, x1 + x2))

RuntimeError: maximum recursion depth exceeded

Comments