3

I want to use lambdas as functions that return objects. Take a look at lambda x: print(item) , as it is written, the expected result is that holder[str(item)] will store a function that returns the current item. But my code shows that it always returns the last item.

Why this happens? And is there a way to pass functions that actually return the item?

items = [1,2,3]
holder = {}

for item in items:
    holder[str(item)] = lambda x: print(item)

holder['1'](None)
holder['2'](None)
holder['3'](None)

Output:

3
3
3

Expected behavior would be:

1
2
3
Guerlando OCs
  • 1,886
  • 9
  • 61
  • 150
  • 2
    You can use [`partial()`](https://docs.python.org/3/library/functools.html?highlight=functools%20partial#functools.partial) instead of `lambda` – Martin Evans Jul 18 '19 at 20:12
  • 1
    *Every* lambda expression defines a function that returns an object. – chepner Jul 18 '19 at 20:14
  • 1
    you need to do `lambda x, i=item: print(i)` to put the local `item` in the lambda's closure. You can see that it makes sense that all of them are the last one, as this is the last value the variable `item` is assigned to – Tomerikoo Jul 18 '19 at 20:15

1 Answers1

3

You could use partial() instead of using lambda:

from functools import partial


items = [1,2,3]
holder = {}

for item in items:
    holder[str(item)] = partial(print, item)

holder['1'](None)
holder['2'](None)
holder['3'](None)

Giving an output of:

1 None
2 None
3 None
Martin Evans
  • 45,791
  • 17
  • 81
  • 97