From: ceciliaseidel on
As you were talking about list.pop()...

Is anyone able to reproduce the following and explain why this happens
by chance? (Using 3.1.1)

l1 = ["ready", "steady", "go"]
l2 = ["one", "two", "tree"]
l3 = ["lift off"]

for w in l1:
print(l1.pop()) #prints only "go steady" - why not "ready"??

for w in range(len(l2)):
print(l2.pop()) #prints "three two one" as expected

for w in l3:
print(l3.pop()) #prints "lift off" - inconsistent to first case...


At least for 2.2.3 I found the first way to iterate the list as default,
I guess it is deprecated now but still what happens seems weird to me...
From: Arnaud Delobelle on
ceciliaseidel(a)gmx.de writes:

> As you were talking about list.pop()...
>
> Is anyone able to reproduce the following and explain why this happens
> by chance? (Using 3.1.1)
>
> l1 = ["ready", "steady", "go"]
> l2 = ["one", "two", "tree"]
> l3 = ["lift off"]
>
> for w in l1:
> print(l1.pop()) #prints only "go steady" - why not "ready"??
>

I suggest you simulate the loop above using pen and paper, writing the
value of w and the value of l1 at each iteration. The behaviour you are
observing should then be clearly explained. And you should also realise
that it's a really bad idea to mutate a list that you are iterating on!

HTH

--
Arnaud
From: Alf P. Steinbach on
* ceciliaseidel(a)gmx.de:
> As you were talking about list.pop()...
>
> Is anyone able to reproduce the following and explain why this happens
> by chance? (Using 3.1.1)
>
> l1 = ["ready", "steady", "go"]
> l2 = ["one", "two", "tree"]
> l3 = ["lift off"]
>
> for w in l1:
> print(l1.pop()) #prints only "go steady" - why not "ready"??
>
> for w in range(len(l2)):
> print(l2.pop()) #prints "three two one" as expected
> for w in l3:
> print(l3.pop()) #prints "lift off" - inconsistent to first case...
>
>
> At least for 2.2.3 I found the first way to iterate the list as default,
> I guess it is deprecated now but still what happens seems weird to me...

Arnaud Delobelle has already answered your question, but you might alternatively
try this angle:


l1 = ["ready", "steady", "go"]
l2 = ["one", "two", "tree"]
l3 = ["lift off"]

for w in l1:
print( w, l1 )
print(l1.pop()) #prints only "go steady" - why not "ready"??

for w in range(len(l2)):
print(l2.pop()) #prints "three two one" as expected
for w in l3:
print( w, l3 )
print(l3.pop()) #prints "lift off" - inconsistent to first case...


If the list has at least one item you always get into the first iteration of the
loop. I.e. there's no inconsistency, unless you count the lack of an exception
as an inconsistency. I don't know whether the behavior is clearly defined or
not; there is a possibility that it might be well-defined.


Cheers & hth.,

- Alf
From: ceciliaseidel on


Arnaud Delobelle schrieb:
> ceciliaseidel(a)gmx.de writes:
>
>> As you were talking about list.pop()...
>>
>> Is anyone able to reproduce the following and explain why this happens
>> by chance? (Using 3.1.1)
>>
>> l1 = ["ready", "steady", "go"]
>> l2 = ["one", "two", "tree"]
>> l3 = ["lift off"]
>>
>> for w in l1:

Ouch... thanks Arnaud... The stable way would've been

for w in l1[:]: #use copy of l1 for iteration
print(l1.pop()) #decomposite list

(just in case any other newbie is reading this...)


>> print(l1.pop()) #prints only "go steady" - why not "ready"??
>>
>
> I suggest you simulate the loop above using pen and paper, writing the
> value of w and the value of l1 at each iteration. The behaviour you are
> observing should then be clearly explained. And you should also realise
> that it's a really bad idea to mutate a list that you are iterating on!
>
> HTH
>

From: Roel Schroeven on
Op 2010-01-23 17:29, ceciliaseidel(a)gmx.de schreef:
>
>
> Arnaud Delobelle schrieb:
>> ceciliaseidel(a)gmx.de writes:
>>
>>> As you were talking about list.pop()...
>>>
>>> Is anyone able to reproduce the following and explain why this happens
>>> by chance? (Using 3.1.1)
>>>
>>> l1 = ["ready", "steady", "go"]
>>> l2 = ["one", "two", "tree"]
>>> l3 = ["lift off"]
>>>
>>> for w in l1:
>
> Ouch... thanks Arnaud... The stable way would've been
>
> for w in l1[:]: #use copy of l1 for iteration
> print(l1.pop()) #decomposite list

I would prefer:

while l1:
print(l1.pop())

--
The saddest aspect of life right now is that science gathers knowledge
faster than society gathers wisdom.
-- Isaac Asimov

Roel Schroeven