Python has both generator functions and generator expressions. A generator function is like this:
def int_generator():
i = 0
while True:
yield i
i += 1
A generator expression looks like a list comprehension (a Python construct based on the set-builder notation in Math) and is used in situations where you don't really need to materialize the list - for example when you are just iterating over it in a `for` loop:
for n, square in ((i, i * i) for i in int_generator()):
print(f"{n}² = {square}")
time.sleep(1)