#πŸ”’ can someone explain me why arg used in the code below

69 messages Β· Page 1 of 1 (latest)

lavish moon
#

is_even_list = [lambda arg=x: arg * 10 for x in range(1, 5)]
for item in is_even_list:
print(item())

sullen brookBOT
#

@lavish moon

Python help channel opened

Remember to:

  • Ask your Python question, not if you can ask or if there's an expert who can help.
  • Show a code sample as text (rather than a screenshot) and the error message, if you've got one.
  • Explain what you expect to happen and what actually happens.

:warning: Do not pip install anything that isn't related to your question, especially if asked to over DMs.

outer leaf
#

what is the output you observed when erasing arg=x?

lavish moon
#

wait a sec

#

Traceback (most recent call last):
File "D:\pythonProject\first file.py", line 6, in <module>
print(item())
^^^^^^
TypeError: <lambda>() missing 1 required positional argument: 'x'

outer leaf
#

no, not even with x remaining

#

only like lambda: x * 10

#

not lambda x: x * 10

lavish moon
#

ok

#

40
40
40
40

outer leaf
#

yeah

#

so the thing with lambdas is that

#

the names used in its body are looked up lately

#

meaning, it looks it up only at the time of execution, not definition

lavish moon
#

ohh

outer leaf
#

if we consider this:

#
[lambda: x * 10 for x in range(1, 5)]
#

this is a list of 4 lambdas alright

#

but after this list is made, when you call any of them

#

it will attempt x * 10 right?

#

but what is x?!

lavish moon
#

yess

outer leaf
#

it didn't "register" it when defining, so it goes back to its definition scope at the execution time and sees what the x is

#

and guess what

#

x was last 4 there

#

right?

lavish moon
#

yess

outer leaf
#

after the list is made, x was left off 4

#

so all of them uses 4

#

and we get 40 40 40 40

#

makes sense?

#

people came up with "solutions" to this

lavish moon
#

then how can i get the desired output

outer leaf
#

one way is making a "dummy" parameter like your original code had

lavish moon
#

ok

outer leaf
#

somewhat more confusingly, convention is like:

[lambda x=x: x * 10 for x in range(1, 5)]
#

this forces early binding if you will

#

because at the definition time, x must be evaluated

#

but here there is 2 xs, which is confusing

#

so your code is better in that sense:

#
[lambda arg=x: arg * 10 for x in range(1, 5)]
#

here, when the lambdas are being defined, their default values for parameters are defined at that time

#

and x is each turn appointed to arg with 1, 2, 3 and 4

#

this way you captured the definition-time x into arg

#

so when you further call the lambdas with no argument like item() you did

#

default values will be used

#

and the default values were correctly registered at definition time with desired values of 1, 2, 3 and 4

#

so we get 10 20 30 40 as expected

lavish moon
#

can i connect with u personally

#

?

outer leaf
#

in a spiritual level? :p

lavish moon
#

noop

#

as a student ig

#

i got lots of doubts

outer leaf
#

i mean you can ask questions here i'm not always available as you expect

lavish moon
#

or we can be friends

outer leaf
#

sure

spare marten
outer leaf
#

alluding to late binding

spare marten
spare marten
outer leaf
#

i meant late-ly :p

#

English strikes me again

outer leaf
#

:p i think i have at least threeteen now

spare marten
#

onety three

#

😎

sullen brookBOT
#
Python help channel closed

This help channel has been closed and it's no longer possible to send messages here. If your question wasn't answered, feel free to create a new post in #1035199133436354600. To maximize your chances of getting a response, check out this guide on asking good questions.