context not cleaned at the end of a loop containing yield?

T

TP

Hi everybody,

This example gives strange results:

########
def foo( l = [] ):

l2 = l
print l2
for i in range(10):
if i%2 == 0:
l2.append( i )
yield i
########
[]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[0, 2, 4, 6, 8]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[0, 2, 4, 6, 8, 0, 2, 4, 6, 8]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
....

How to explain this behavior? Why l is not [] when we enter again the
function foo()?

Thanks

Julien

--
python -c "print ''.join([chr(154 - ord(c)) for c in '*9(9&(18%.\
9&1+,\'Z4(55l4('])"

"When a distinguished but elderly scientist states that something is
possible, he is almost certainly right. When he states that something is
impossible, he is very probably wrong." (first law of AC Clarke)
 
M

MRAB

TP said:
Hi everybody,

This example gives strange results:

########
def foo( l = [] ):

l2 = l
print l2
for i in range(10):
if i%2 == 0:
l2.append( i )
yield i
########
[i for i in ut.foo()]
[]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[i for i in ut.foo()]
[0, 2, 4, 6, 8]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[i for i in ut.foo()]
[0, 2, 4, 6, 8, 0, 2, 4, 6, 8]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
...

How to explain this behavior? Why l is not [] when we enter again the
function foo()?
Read http://www.ferg.org/projects/python_gotchas.html#contents_item_6
 
M

Mensanator

TP said:
Hi everybody,
This example gives strange results:
########
def foo( l = [] ):
    l2 = l
    print l2
    for i in range(10):
        if i%2 == 0:
            l2.append( i )
        yield i
########
[i for i in ut.foo()]
[]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[i for i in ut.foo()]
[0, 2, 4, 6, 8]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[i for i in ut.foo()]
[0, 2, 4, 6, 8, 0, 2, 4, 6, 8]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
...
How to explain this behavior? Why l is not [] when we enter again the
function foo()?

Readhttp://www.ferg.org/projects/python_gotchas.html#contents_item_6- Hide quoted text -

So, l=[] only happens once, not everytime you call it.

Also, 12 = l means 12 is the same object and remembers it's contents
across calls
(since l is never reset).

Try this:

def foo(l=[0]):
l2 = l[1:] # deep copy, omitting call count
print l2,l2 is l,l
l[0] += 1 # count how many times we call foo
for i in range(10):
if i%2 == 0:
l2.append(i)
yield i
[] False [0]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[] False [1]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[] False [2]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

You can see that l is not being reset to [0] on subsequent calls
and that 12 is a seperate list from l, so appending to l2 does not
change l.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top