Weird lambda rebinding/reassignment without me doing it

David C. Ullrich dullrich at sprynet.com
Thu Jul 10 12:12:15 EDT 2008


In article 
<02ff4326-7b07-4ae6-8607-f58ea61802ef at z72g2000hsb.googlegroups.com>,
 ssecorp <circularfunc 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
(unless it specifies "global"). It doesn't reassign anything.
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:

>>> def DoesntReassign(x):
...   x = 0
... 
>>> def Modifies(x):
...   x.append(0)
... 
>>> x=42
>>> DoesntReassign(x)
>>> x
42
>>> x=[]
>>> Modifies(x)
>>> x
[0]

Hmm, look at this:

>>> x=[]
>>> id(x)
404296
>>> Modifies(x)
>>> x
[0]
>>> id(x)
404296

'x' refers to exactly the same object before and after
the call to Modifies. The function has _modified_ that
object, but it hasn't redefined or reassigned anything.

> Doesnt Python have closure or that isnt what this is about?
> 
> 
> def validate(placed):
>     student = round(random.random()*401)
>     if student in placed:
>         return validate(placed)
>     else:
>         placed.append(student)
>         return student, placed
> 
> def val(placed):
>     student = round(random.random()*401)
>     if student in placed:
>         return validate(placed)
>     else:
>         placed.append(student)
>         return student
> 
> 
> 
> >>> g = lambda x:validate(x)
> >>> l=[]
> >>> for x in range(1,10):
> 	g(l)
> 
> 
> (141.0, [141.0])
> (19.0, [141.0, 19.0])
> (86.0, [141.0, 19.0, 86.0])
> (120.0, [141.0, 19.0, 86.0, 120.0])
> (76.0, [141.0, 19.0, 86.0, 120.0, 76.0])
> (262.0, [141.0, 19.0, 86.0, 120.0, 76.0, 262.0])
> (234.0, [141.0, 19.0, 86.0, 120.0, 76.0, 262.0, 234.0])
> (74.0, [141.0, 19.0, 86.0, 120.0, 76.0, 262.0, 234.0, 74.0])
> (325.0, [141.0, 19.0, 86.0, 120.0, 76.0, 262.0, 234.0, 74.0, 325.0])
> >>> g = lambda x:val(x)
> >>> l=[]
> >>> for x in range(1,10):
> 	g(l)
> 
> 
> 183.0
> 33.0
> 315.0
> 244.0
> 308.0
> 168.0
> 146.0
> 378.0
> 297.0
> >>>

-- 
David C. Ullrich



More information about the Python-list mailing list