"""
Demonstrate generators and lazy computation
"""
# review range
print range(10)
# Print a million elements, type ^C to stop
# for i in range(1000000): print i
# Try to print a billion elements, fails with MemoryError
# for i in range(1000000000): print i
# Use xrange not range for a billion elements, type ^C to stop
# for i in xrange(1000000000): print i
# range is eager - computes all the elements first
# xrange is lazy - computes each element as needed
# Python generators code lazy computation,
# remember values of local variables between calls
def my_xrange(size):
i = -1
while True:
i += 1
if i < size:
yield i # yield not return makes generator
else:
raise StopIteration # how to exit from generator
for i in my_xrange(3): print i
# generate a billion elements
# for i in my_xrange(1000000000): print i # ^C to stop
# Generator expressions are like list comprehensions, but lazy
# one hundred million elements
# list comprehension fails with MemoryError after 20+ sec
# sum([2*i for i in xrange(100000000)])
# one hundred million elements
# generator expression returns result after 20+ sec
# sum(2*i for i in xrange(100000000))