Generator
Iterable Objects
#!/usr/bin/python

#list
l = range(10);
for i in l:
    print i;

#tuple
t = (1, 2, 3, 4);
for i in t:
    print i;

#dict
d = {'x':1, 'y':2};
for k in d:
    print k;

#string
s = 'Hello World!';
for i in s:
    print i;
		
Iterator
#!/usr/bin/python

l = iter(range(10)); #iterator

try:
    while True:
        print l.next(); #if no more element, raise StopIteration
except StopIteration:
    pass
		
Implement Iterator as Classes
#!/usr/bin/python

class yrange:
    def __init__(self, n):
        self.i = 0
        self.n = n

    def __iter__(self): # make an object iterable
        return self # return an iterator

    def next(self):
        if self.i < self.n:
	              i = self.i
	              self.i += 1
	              return i
	          else:
	              raise StopIteration()

y = yrange(10);

l = list(y); # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
print l;
l = list(y); # []
print l;
		
#!/usr/bin/python


class zrange:
    def __init__(self, n):
        self.n = n

    def __iter__(self):
        return zrange_iter(self.n)

class zrange_iter:
    def __init__(self, n):
	          self.i = 0
	          self.n = n

	      def __iter__(self):
	          # Iterators are iterables too.
	          # Adding this functions to make them so.
	          return self

	      def next(self):
	          if self.i < self.n:
	              i = self.i
	              self.i += 1
	              return i
	          else:
	              raise StopIteration()

l = zrange(10);

print list(l); # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
print list(l); # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
		
Generator
#!/usr/bin/python

def yrange(n):
    i = 0;
    while i < n:
    	yield i;
	i += 1;

l = yrange(10);
for i in l:
	print i;

for i in l: # do not print anything, l has been consumed
	print i;
		
Generator Expression
#!/usr/bin/python

# list
l = [x*x for x in range(4)]; # [0, 1, 4, 9]
print l;

# generator
g = (x*x for x in range(4));
for i in g:
	print i;
		
Reference