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