# Python Generator - How to create or iterate a generator

The Python generator (expression) is declared on the fly as follows:

```
a = [1, 3, 5]
g = (i * i for i in a)
print(g)
# <generator object <genexpr> at 0x11940ef90>
for x in g:
print(x)
# 1
# 9
# 25
```

Precisely, `g`

is a generator expression called "generator", which is fuzzy and not the form or expression of a list-like object. `g`

is a generator, not a list (nor list comprehension). A generator generates values in the for loop but doesn't save those in memory. Meanwhile, all the elements of a list are saved in memory. Generator uses memory efficiently.

You can't get each element a generator generates by an index.

```
a = [1, 3, 5]
g = (i * i for i in a)
print(g[0])
# TypeError: 'generator' object is not subscriptable
```

You can iterate what a generator generates.

```
a = [2, 3, 4]
g = (i + 100 for i in a)
for x in g:
print(x)
# 102
# 103
# 104
```

Another example:

```
g = (i * i for i in range(6))
for x in g:
print(x)
# 0
# 1
# 4
# 9
# 16
# 25
```

An empty list can be an "empty" generator.

```
a = []
g = (i * i for i in a)
for x in g:
print(x)
#
```

## A generator generates values once

```
g = (i * i for i in range(6))
for v in g:
print(v)
print('***')
for w in g:
print(w)
# 0
# 1
# 4
# 9
# 16
# 25
# ***
```

`v`

are iterated and the square numbers (0-25) are printed. But `w`

in g isn't iterated. The generator generates all values in the first loop. The next example shows a generator can stop generating in the loop and start again in the next loop.

```
g = (i * i for i in range(6))
j = 0
for v in g:
j += 1
if j < 4:
print(v)
else:
break
print('***')
for w in g:
print(w)
# 0
# 1
# 4
# ***
# 16
# 25
```

## Generator and next

You can get the item of a generator expression using `next()`

, which is a Python built-in function and returns "next value" of generator.

```
g = (i * i for i in range(6))
print(next(g)) # 0
print(next(g)) # 1
print(next(g)) # 4
print(next(g)) # 9
print(next(g)) # 16
print(next(g)) # 25
print(next(g)) # StopIteration
```

First, `next()`

returns 0 because it's the first time to generate `i * i`

. 6th `next()`

returns 25 but the next doesn't exist. So the last `next()`

raises a StopIteration.

## Convert a Python generator to a Python list or set

You can convert a Python generator to a list.

```
a = [1, 2, 3]
g = (i * i for i in a)
b = list(g)
print(b)
# [1, 4, 9]
```

Also you can convert a generator to a set.

```
a = [1, 2, 3]
g = (i * i for i in a)
b = set(g)
print(b)
# {1, 4, 9}
```

## Length of generator

The `len()`

can't take a Python generator.

```
g = (i * i for i in range(5))
c = len(g) # TypeError: object of type 'generator' has no len()
```

So, to get the length of a generator, convert it to a list.

```
g = (i * i for i in range(5))
s = list(g)
c = len(s) # TypeError: object of type 'generator' has no len()
print(s) # [0, 1, 4, 9, 16]
print(c) # 5
```

## Sum of values generated

```
g = (i * i for i in range(5))
m = sum(g)
print(m) # 30
```

The `sum()`

sums all the elements generated. You don't need to convert a generator to a list to sum.

```
g = (i * i for i in range(5))
s = list(g)
m = sum(s)
```

## Comments

Powered by Markdown