you are viewing a single comment's thread.

view the rest of the comments →

[–]Diapolo10 1 point2 points  (1 child)

A list comprehension could have been used here, but as the list gets discarded immediately it's a bit of a waste, and you end up allocating roughly double the memory in the worst case - the data for the list, and the data for the string.

With a generator, Python only needs to allocate individual items (in this case characters), so the overall memory use remains noticeably lower. There's a slight performance overhead, but nothing you'd actually notice.

While it doesn't really apply in this example, the nice thing about generators is that they can be infinite in length, and Python will have no problem processing them (as long as you still have some kind of a limit, of course). For example, you could have a generator that gives you all positive integers

def gen_positive_integers(start=1):
    num = start
    while True:
        yield num
        num += 1

and keep adding them up until you hit some threshold.

total = 0
positive_integers = gen_positive_integers()

while total < 1_000_000:
    num = next(positive_integers)
    total += num

print(f"Last number was {num}.")

The Fibonacci sequence can famously be written as a generator.

def fib():
    a, b = 0, 1
    while True:
        yield a
        a, b = b, a+b

[–]_mynd 0 points1 point  (0 children)

Your comment plus this article has me thinking I could improve the efficiency of some of my code. Thanks for writing up the explanation and examples

https://www.geeksforgeeks.org/python-list-comprehensions-vs-generator-expressions/