iterating lists

C

ceciliaseidel

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...
 
A

Arnaud Delobelle

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
 
A

Alf P. Steinbach

* (e-mail address removed):
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
 
C

ceciliaseidel

Arnaud said:
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...)
 
R

Roel Schroeven

Op 2010-01-23 17:29, (e-mail address removed) schreef:
Arnaud said:
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
 
S

Stefan Behnel

(e-mail address removed), 23.01.2010 17:29:
Arnaud said:
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

If the intention is to exhaust the list during the iteration, I'd go for this:

while l1:
print(l1.pop())

Stefan
 
S

Steven D'Aprano

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

I would prefer:

while l1:
print(l1.pop())


I would prefer:

for x in reversed(l1):
print(x)
l1[:] = []


And garbage dispose of the entire list in one go, instead of an item at a
time.
 
S

Stefan Behnel

Steven D'Aprano, 23.01.2010 18:44:
for w in l1[:]: #use copy of l1 for iteration
print(l1.pop()) #decomposite list
I would prefer:

while l1:
print(l1.pop())


I would prefer:

for x in reversed(l1):
print(x)
l1[:] = []


And garbage dispose of the entire list in one go, instead of an item at a
time.

IIRC, that's what CPython does anyway, so no need to make this more complex
than necessary.

Stefan
 

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

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top