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.
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.
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.
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.
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.
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 chain
ed 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())
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.
You can build a generator by saying
(x for x in List)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With