David542
David542

Reputation: 110163

Using return (list) vs yield

I've created two enumeration methods, one which returns a list and the other which returns a yield/generator:

def enum_list(sequence, start=0):
    lst = []
    num = start
    for sequence_item in sequence:
        lst.append((num, sequence_item))
        num += 1
    return lst


def enum_generator(sequence, start=0):
    num = start
    for sequence_item in sequence:
        yield (num, sequence_item)
        num += 1

A few questions on this:

(1) Is changing a list to a generator as simple as doing:

# build via list
l = list()
for item in items:
    l.append(item)

# build via iterator
# l = list() (1) <== delete this line
for item in items:
    yield item # (2) change l.append(...) to yield ...

(2) Is "lazy evaluation" the only reason to use a generator, or are there other reasons as well?

Upvotes: 2

Views: 2447

Answers (2)

Gnudiff
Gnudiff

Reputation: 4305

An additional difference in your case is that since list is created before use and generator is evaluated at each next call, the generator function can check the context and come to different result for each yield, depending on external conditions, which vary with time.

Consider pseudocode:

def alloted_time():
    while True:
         if len(global_queue)>10:
            yield 5
         else:
            yield 10

If queue is large, allot 5 mins for next person, else 10.

Upvotes: 0

Florian Bernard
Florian Bernard

Reputation: 2569

(1) generator are simply created as adding yield to your iteration.

(2) Yes, for lazy evaluation. But generators are also used to create stack and queue as they can be only iterate once. This property is also exploited in context manager, by yielding the context.

Upvotes: 1

Related Questions