Python has a quite mighty tool: Generators.
Generators help you to program iterators. They look almost like normal functions, but they have yield as a special keyword. yield is used instead of return.
Imagine you wanted to display n Fibonacci numbers. This could be your normal approach:
#!/usr/bin/python # -*- coding: utf-8 -*- def fibonacci(n): """ Build and return a list of the first n >= 2 Fibonacci numbers """ fibList = [1, 1] while len(fibList) < n: newFib = fibList[-1] + fibList[-2] fibList.append(newFib) return fibList for nr, fib in enumerate(fibonacci(100)): print("The %i-th Fibonacci-Nr is %i" % (nr, fib))
The disadvantage of this approach is that you have to keep every element of the sequence in memory. Of course, you could write something like this:
#!/usr/bin/python # -*- coding: utf-8 -*- def fib(n): """ Calculate the n-th fibonacci number. """ if n == 0: return 0 elif n == 1: return 1 else: return fib(n-1) + fib(n-2) for nr in xrange(1, 100): print("The %i-th Fibonacci-Nr is %i" % (nr, fib(nr)))
This needs much less memory, but much more time. You have to recalculate the first few fibonacci numbers every time.
A generator could look like this:
#!/usr/bin/python # -*- coding: utf-8 -*- def fibGenerator(): """ A python fibonacci generator """ a, b = 1, 1 while 1: yield a a, b = b, a + b myGenerator = fibGenerator() for nr in xrange(1,100): print("The %i-th Fibonacci-Nr is %i" % (nr, myGenerator.next()))