Weird lambda rebinding/reassignment without me doing it
ssecorp
circularfunc at gmail.com
Thu Jul 10 16:40:12 EDT 2008
ty very good answer. i know i shouldn't use lambda like that, i never
do i was just playing around there and then this happened which i
thought was weird.
On Jul 10, 8:09 pm, Terry Reedy <tjre... at udel.edu> wrote:
> David C. Ullrich wrote:
> > In article
> > <02ff4326-7b07-4ae6-8607-f58ea6180... at z72g2000hsb.googlegroups.com>,
> > ssecorp <circularf... at gmail.com> wrote:
>
> >> I am never redefining the or reassigning the list when using validate
> >> but since it spits the modified list back out that somehow means that
> >> the modified list is part of the environment and not the old one.
> >> i thought what happend inside a function stays inside a function
> >> meaning what comes out is independent of what comes in.
> >> Meaning if I want the list I send as a parameter to the function I
> >> have to do x = func(x) and not just func(x) and x is magically what
> >> comes out of func().
>
> > A function cannot modify the value of a global variable
>
> Yes it can.
> >>> a=[]
> >>> def f():
> a.append('yes I can')
>
> >>> f()
> >>> a
> ['yes I can']
>
> > (unless it specifies "global"). It doesn't reassign anything.
>
> The statement 'global a' would allow f to *rebind* the global *name*
> 'a'. The word 'variable' should almost not be used in discussing Python
> since it is often unclear whether it refers to a name (or collection
> slot) or an object bound thereto.
>
> > But in the functions below you're not reassigning a variable,
> > you're _modifiying_ an object. A function _can_ modify an
> > object you pass to it:
>
> It can modify any mutable object it can access.
>
> >> Doesnt Python have closure or that isnt what this is about?
>
> Python does have closures. This is not about that.
>
> >> def validate(placed):
> >> student = round(random.random()*401)
> >> if student in placed:
> >> return validate(placed)
> >> else:
> >> placed.append(student)
> >> return student, placed
>
> Delete this. It is redundant with the below.
>
> >> def val(placed):
> >> student = round(random.random()*401)
> >> if student in placed:
> >> return validate(placed)
> >> else:
> >> placed.append(student)
> >> return student
>
> I believe this is equivalent to
>
> def addval(placed):
> while True:
> student = round(random.random()*401)
> if student not in placed:
> break
> placed.append(student)
> return student
>
> While this avoids the indefinite recursion depth problem, it does not
> avoid the indefinite time problem. Use random.shuffle, or write your
> own version if doing this for practice. Also consider removing the
> return statement unless you actually directly use the added value. It
> is easier to remember that addval mutates 'placed' without the return.
>
> >>>>> g = lambda x:validate(x)
>
> This is doubly diseased.
>
> First, never write a 'name = lambda...' statement since it is equivalent
> to a def statement except that the resulting function object lacks a
> proper .funcname attribute. The above only trivially abbreviates
> def g(x): return validate(x)
> by 3 characters. Another reason is that the lambda form somehow more
> often tricks people into the next mistake .
>
> Second, never write a function (with either def or lambda) that simply
> returns a function of the argument(s). The wrapping does nothing! This
> is a waste of time and space for both you and the interpreter. The
> above is functionally equivalent to
> g = validate
> and if you want that, you could name the function 'g' when you define it.
>
> >>>>> l=[]
>
> In some fonts, 'l' and '1' are nearly identical; please use something
> else for public code, which you made this to be by posting it;-)
>
> >>>>> for x in range(1,10):
> >> g(l)
>
> As said, the 'g' wrapper is useless.
> addval(l)
>
> Hope this helps.
>
> Terry Jan Reedy
More information about the Python-list
mailing list