A number of times I've thought that generator style can be more direct that returning a list, for example,
def foo(input_array): for x in input_array: yield processed(x)
vs.
def bar(input_array): accumulator = [] for x in input_array: accumulator.append(processed(x)) return accumulator
(okay, if it were really that simple, I'd write map
, but you get the point: the generator version is cleaner). However, a return type of a generator is not always desired. Is there a built-in decorator that I can use to change foo
into a function returning a list or tuple? The way I'd write it myself is,
import functools def transform_return_value(transformer): def inner(f): @functools.wraps(f) def new_f(*argv, **kwargs): return transformer(f(*argv, **kwargs)) return new_f return inner @transform_return_value(list) def foo(input_array): for x in input_array: yield processed(x)
It uses yield instead of return keyword. So, this will return the value against the yield keyword each time it is called. However, you need to create an iterator for this function, as shown below. The generator function cannot include the return keyword.
You can assign this generator to a variable in order to use it. When you call special methods on the generator, such as next() , the code within the function is executed up to yield . When the Python yield statement is hit, the program suspends function execution and returns the yielded value to the caller.
A return statement in a generator, when executed, will make the generator finish (i.e. the done property of the object returned by it will be set to true ). If a value is returned, it will be set as the value property of the object returned by the generator.
To the best of my knowledge (and I've looked, because I've wondered exactly the same thing), no: there is no direct way of doing this with the standard library.
There is a thoroughly tested listify
wrapper in unstdlib.py library, though: https://github.com/shazow/unstdlib.py/blob/master/unstdlib/standard/list_.py#L149
def listify(fn=None, wrapper=list): """ A decorator which wraps a function's return value in ``list(...)``. Useful when an algorithm can be expressed more cleanly as a generator but the function should return an list. Example:: >>> @listify ... def get_lengths(iterable): ... for i in iterable: ... yield len(i) >>> get_lengths(["spam", "eggs"]) [4, 4] >>> >>> @listify(wrapper=tuple) ... def get_lengths_tuple(iterable): ... for i in iterable: ... yield len(i) >>> get_lengths_tuple(["foo", "bar"]) (3, 3) """ def listify_return(fn): @wraps(fn) def listify_helper(*args, **kw): return wrapper(fn(*args, **kw)) return listify_helper if fn is None: return listify_return return listify_return(fn)
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