I'm having a little trouble understanding the results of the below snippet, and think it's because I'm confused about function binding. Why would the following snippets produce different results?
import itertools
def make_funcs(lst):
for val in lst:
def f():
return sum(1 for i in range(10) if i > val)
f.func_name = ">" + str(val)
yield f
## examples:
for f in make_funcs(range(2)):
print(f.func_name, f())
## prints:
>0 9
>1 8
## works as expected:
for f in make_funcs(range(2)):
for g in make_funcs(range(2)):
print(f.func_name, g.func_name, f() + g())
## prints:
>0 >0 18
>0 >1 17
>1 >0 17
>1 >1 16
while on the other hand:
## provides results that are counter-intuitive (to me, at least)
for f, g in itertools.product(make_funcs(range(2)), make_funcs(range(2))):
print(f.func_name, g.func_name, f() + g())
## prints:
>0 >0 16
>0 >1 16
>1 >0 16
>1 >1 16
It appears to me that it's only grabbing/using/binding
the last variable in each implicit for
-loop for the calculation, even though it's grabbing the correct variable for the function names.
What am I missing about scoping or function definitions or closures (or whatever) that's causing these results?
NB: if any of the tags I put on this question are irrelevant, feel free to remove them - I put them all because I'm not sure what the issue is.