I wrote two function f and g with same functionality
def f(l, count):
if count > 1:
for i in f(l, count-1):
yield i + 1
else:
yield from l
for i in f(range(100000),900):
pass
print('f')
and
def g(l, count):
if count > 1:
tmp = []
for i in g(l, count-1):
tmp.append(i+1)
return tmp
else:
return l
for i in g(range(100000),900):
pass
print('f')
and i I think f shuold be faster but g is faster when in run it
time for g
real 0m5.977s
user 0m5.956s
sys 0m0.020s
time for f
real 0m7.389s
user 0m7.376s
sys 0m0.012s
There are a couple of big differences between a solution that yields a result and one that computes the complete result.
The yield keeps returning the next result until exhausted while the complete calculation is always done fully so if you had a test that might terminate your calculation early, (often the case), the yield method will only be called enough times to meet that criteria - this often results in faster code.
The yield result only consumes enough memory to hold the generator and a single result at any moment in time - the full calculation consumes enough memory to hold all of the results at once. When you get to really large data sets that can make the difference between something that runs regardless of the size and something that crashes.
So yield is slightly more expensive, per operation, but much more reliable and often faster in cases where you don't exhaust the results.