1

I am attempting to perform a fairly simple lambda function which would print the multiplication table.

For some odd reason when I populate the dictionary manually, it works.

lamdic = {
    'x0': lambda num: num * 1,
    'x1': lambda num: num * 2,
    'x2': lambda num: num * 3,
    'x3': lambda num: num * 4,
    'x4': lambda num: num * 5,
    'x5': lambda num: num * 6,
    'x6': lambda num: num * 7,
    'x7': lambda num: num * 8,
    'x8': lambda num: num * 9,
    'x9': lambda num: num * 10
}

However, if I try to use a for loop to perform the very same thing - it doesn't.

for i, l in enumerate(vlst):
    lamdic.update({l: lambda num: num * (i + 1)})

I've printed out the dictionary items and they appear to be populating in the same structure, yet the for loop doesn't print correctly.

Full code:

vlst = ['x' + str(num) for num in range(10)]
lamdic = {}

for i, l in enumerate(vlst):
    lamdic.update({l: lambda num: num * (i + 1)})

for v in vlst:
    for i in range(1, len(vlst) + 1):
        print(lamdic[v](i), end=' ')
    print()

Manual assignment result (expected):

1 2 3 4 5 6 7 8 9 10 
2 4 6 8 10 12 14 16 18 20 
3 6 9 12 15 18 21 24 27 30 
4 8 12 16 20 24 28 32 36 40 
5 10 15 20 25 30 35 40 45 50 
6 12 18 24 30 36 42 48 54 60 
7 14 21 28 35 42 49 56 63 70 
8 16 24 32 40 48 56 64 72 80 
9 18 27 36 45 54 63 72 81 90 
10 20 30 40 50 60 70 80 90 100

For loop assignment (unexpected):

2 6 12 20 30 42 56 72 90 110 
2 6 12 20 30 42 56 72 90 110 
2 6 12 20 30 42 56 72 90 110 
2 6 12 20 30 42 56 72 90 110 
2 6 12 20 30 42 56 72 90 110 
2 6 12 20 30 42 56 72 90 110 
2 6 12 20 30 42 56 72 90 110 
2 6 12 20 30 42 56 72 90 110 
2 6 12 20 30 42 56 72 90 110 
2 6 12 20 30 42 56 72 90 110

Why is there a difference? Why is doing (basically) the same thing returns a different result?

Kfir Cohen
  • 153
  • 1
  • 3
  • 13
  • 2
    Does this answer your question? [Lambda in a loop](https://stackoverflow.com/questions/19837486/lambda-in-a-loop) – mcsoini May 31 '21 at 12:20
  • @mcsoini - Yes, it does! Thank you very much! The question you posted led me to the Python Programming FAQ which explains it very well. https://docs.python.org/3/faq/programming.html#why-do-lambdas-defined-in-a-loop-with-different-values-all-return-the-same-result – Kfir Cohen May 31 '21 at 12:42

1 Answers1

0

Thanks to @mcsoini for referring me to the answer.

The problem was the value was not bound, and therefore did not change through the iterations.

The fixed code is below:

vlst = ['x' + str(num) for num in range(10)]
lamdic = {}

for i, l in enumerate(vlst):
    lamdic.update({l: lambda num, saved_i=i: num * (saved_i + 1)})

for v in vlst:
    for i in range(1, len(vlst) + 1):
        print(lamdic[v](i), end=' ')
    print()

output (as expected):

1 2 3 4 5 6 7 8 9 10 
2 4 6 8 10 12 14 16 18 20 
3 6 9 12 15 18 21 24 27 30 
4 8 12 16 20 24 28 32 36 40 
5 10 15 20 25 30 35 40 45 50 
6 12 18 24 30 36 42 48 54 60 
7 14 21 28 35 42 49 56 63 70 
8 16 24 32 40 48 56 64 72 80 
9 18 27 36 45 54 63 72 81 90 
10 20 30 40 50 60 70 80 90 100
Kfir Cohen
  • 153
  • 1
  • 3
  • 13