# Iteration in Python

### A simple for-loop

```for i in range(10):
print i,
# Prints 0 1 2 3 4 5 6 7 8 9
# Note that in Python 2.x.x, xrange is better```

### A list comprehension

Create a list in a single line, without the need for an explicit for-loop+append pattern.
```nums_0_to_9 = [i for i in xrange(10)]
# or, of course:
# nums_0_to_9 = range(10)
# but for the squares:
squared_0_to_9 = [i*i for i in xrange(10)]```

### A generator object

Instead of holding the entire list in memory, elements are generated and returned as needed.
```squared_0_to_9 = (i*i for i in xrange(10))
# squared_0_to_9 is not a list, just a generator object. Sample usage:
for n in squared_0_to_9:
print n,
# prints 0 1 4 9 16 25 36 49 64 81```

### A nested list comprehension and generator object

Not for the faint of heart (i.e. not recommended).
```even_squares_0_to_9 = [i_2 for i_2 in (i*i for i in xrange(10))
if i_2 % 2 == 0]```

### Iteration over a "true list"

Let's use some real data. The following list is from a pyohio-organizers e-mail:
```pizza_order = """\
5 pepperoni
5 sausage
5 cheese
2 mushroom
2 onion
1 jalapeno"""

pizza_types = [line.split() for line in pizza_order.split("\n")]
for pizza in pizza_types:
if i_like(pizza):
eat_a_piece(pizza)
# In my case, this would eat a piece of each kind of pizza```

### Iteration with tuple unpacking

```ordered_pizzas = [tuple(line.split())
for line in pizza_order.split("\n")]
for quantity, topping in ordered_pizzas:
if not is_enough(topping, quantity):
order_more(topping)
```
The benefits of Python's iteration model