Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Pythonically yield all values from a list?

Suppose I have a list that I wish not to return but to yield values from. What is the most pythonic way to do that?

Here is what I mean. Thanks to some non-lazy computation I have computed the list ['a', 'b', 'c', 'd'], but my code through the project uses lazy computation, so I'd like to yield values from my function instead of returning the whole list.

I currently wrote it as following:

my_list = ['a', 'b', 'c', 'd']
for item in my_list:
    yield item

But this doesn't feel pythonic to me.

like image 309
bodacydo Avatar asked Mar 23 '10 08:03

bodacydo


People also ask

How do you yield a list in Python?

Using the Yield Keyword The yield keyword, unlike the return statement, is used to turn a regular Python function in to a generator. This is used as an alternative to returning an entire list at once. This will be again explained with the help of some simple examples.

How does yield work in a for loop?

What the yield keyword does is as follows: Each time you iterate, Python runs the code until it encounters a yield statement inside the function. Then, it sends the yielded value and pauses the function in that state without exiting.

What is the difference between return and yield in Python?

Yield is generally used to convert a regular Python function into a generator. Return is generally used for the end of the execution and “returns” the result to the caller statement. It replace the return of a function to suspend its execution without destroying local variables.

What is yield from in Python?

Yield is a keyword in Python that is used to return from a function without destroying the states of its local variable and when the function is called, the execution starts from the last yield statement. Any function that contains a yield keyword is termed a generator.


3 Answers

Since this question doesn't specify; I'll provide an answer that applies in Python >= 3.3

If you need only to return that list, do as Anurag suggests, but if for some reason the function in question really needs to be a generator, you can delegate to another generator; suppose you want to suffix the result list, but only if the list is first exhausted.

def foo():
    list_ = ['a', 'b', 'c', 'd']
    yield from list_

    if something:
        yield this
        yield that
        yield something_else

In versions of python prior to 3.3, though, you cannot use this syntax; you'll have to use the code as in the question, with a for loop and single yield statement in the body.

Alternatively; you can wrap the generators in a regular function and return the chained result: This also has the advantage of working in python 2 and 3

from itertools import chain

def foo():
    list_ = ['a', 'b', 'c', 'd']

    def _foo_suffix():
        if something:
            yield this
            yield that
            yield something_else

    return chain(list_, _foo_suffix())
like image 160
SingleNegationElimination Avatar answered Oct 09 '22 00:10

SingleNegationElimination


Use iter to create a list iterator e.g.

return iter(List)

though if you already have a list, you can just return that, which will be more efficient.

like image 31
Anurag Uniyal Avatar answered Oct 08 '22 22:10

Anurag Uniyal


You can build a generator by saying

(x for x in List)
like image 2
Johannes Charra Avatar answered Oct 08 '22 23:10

Johannes Charra