Let's write code to generate Fibonacci numbers using Python closures, iterators, and generators.
First of all, closure.
Python
def fibonacci_closure():
values = []
def fibonacci():
if not values:
values.append(0)
return values[0]
elif len(values) == 1:
values.append(1)
return values[1]
else:
next_fib = sum(values)
values[0], values[1] = values[1], next_fib
return next_fib
return fibonacci
next_fibonacci = fibonacci_closure()
for i in range(17):
fib = next_fibonacci()
print fib,
result
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987
Next is the iterator.
Python
class FibonacciIterator(object):
def __init__(self):
self.values = []
def __iter__(self):
return self
def next(self):
if not self.values:
self.values.append(0)
return self.values[0]
elif len(self.values) == 1:
self.values.append(1)
return self.values[1]
else:
next_fib = sum(self.values)
self.values[0], self.values[1] = self.values[1], next_fib
return next_fib
for fib in FibonacciIterator():
if fib > 1000:
break
print fib,
result
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987
Finally the generator.
Python
def fibonacci_generator():
values = [0, 1]
yield 0
yield 1
while True:
next_fib = sum(values)
values[0], values[1] = values[1], next_fib
yield next_fib
for fib in fibonacci_generator():
if fib > 1000:
break
print fib,
result
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987
The generator can be written very concisely.
However, it is better to make it into a container because there is an unexpected addiction to writing the generator like this.
Python
class FibonacciGenerator(object):
def __iter__(self):
values = [0, 1]
yield 0
yield 1
while True:
next_fib = sum(values)
values[0], values[1] = values[1], next_fib
yield next_fib
for fib in FibonacciGenerator():
if fib > 1000:
break
print fib,
result
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987
More on this in another article.
-Notes on creating a Python generator
Enjoy!
Recommended Posts