Why lambda in loop requires default?

Jussi Piitulainen jussi.piitulainen at helsinki.fi
Sun Mar 27 11:15:59 EDT 2016


gvim writes:

> Given that Python, like Ruby, is an object-oriented language why
> doesn't this:
>
> def m():
>   a = []
>   for i in range(3): a.append(lambda: i)
>   return a
>
> b = m()
> for n in range(3): print(b[n]())  # =>  2  2  2
>
> ... work the same as this in Ruby:
>
> def m
>   a = []
>   (0..2).each {|i| a << ->(){i}}
>   a
> end
>
> aa = m
> (0..2).each {|n| puts aa[n].()}  # =>  0  1  2

No, I'm not taking this to private correspondence, and *I'm* not going
to talk about why Python "couldn't" do certain things differently when
other languages apparently can.

I don't know Ruby. It looks gibberish to me, but my *guess* is that the
following way to make Python give you what you want is not "fiddling" at
all but the exact *same* thing that Ruby makes you do.

fs = [ (lambda i: (lambda : i))(i) for i in range(3) ]
print([ f() for f in fs ]) # => [0, 1, 2]

The following is the same as above. I find it preferable.

fs = [ (lambda k: (lambda : k))(i) for i in range(3) ]
print([ f() for f in fs ]) # => [0, 1, 2]

And the following may be even more same as your Ruby thing.

fs = list(map(lambda k: (lambda : k), range(3)))
print([ f() for f in fs ]) # => [0, 1, 2]

So it's not at all like Python can't do this at all.



More information about the Python-list mailing list