Generator expressions are a high performance and memory efficient generalization of list comprehensions and generators. Imagine we want to sum up all even number ranging from 1 to 100.

Using list comprehension:

```
even_sum = sum([x for x in range(1, 100)
if x % 2 == 0])
print(even_sum)
#2450
```

This will prove inefficient in the case of a large range because it first creates a list, it iterates over it and then returns the sum. The same result can be achieved with a generator expression:

```
even_sum = sum(x for x in range(1, 100)
if x % 2 == 0)
print(even_sum)
#2450
```

The generator expressions syntax says that it must be enclosed inside parenthesis (). A generator for squares of numbers:

squares = (x * x for x in range(1,10))

This generator can now be converted to a list with:

```
print(list(squares))
# [1, 4, 9, 16, 25, 36, 49, 64, 81]
```

Or, iterate over it with a for loop:

`for item in squares: print(item)`

This’ll print nothing, since a generator can only be iterated over once. To access values from a generator more than once, either save the values in a list, or define and then run the generator again.