Super User
Super User

Reputation: 147

pop() method in python lists doesn't work properly

When I execute the following code in Python 2.7.3:

#!/usr/bin/env python
# -*- coding: utf-8 -*-


class A(object):
    def __init__(self):
        self.s = []


class B(object):
    def __init__(self):
        self.a = A()


class C(object):
    def __init__(self):
        self.b = B()


c = C()

print c.b.a.s

c.b.a.s.append(1)
c.b.a.s.append(2)
c.b.a.s.append(3)
c.b.a.s.append(4)
c.b.a.s.append(5)

print c.b.a.s

for element in c.b.a.s:
    print c.b.a.s.pop()

print c.b.a.s

I get the output:

[]
[1, 2, 3, 4, 5]
5
4
3
[1, 2]

But I expect the for statement pop all the elements in the list and leave c.b.a.s as [].

The question: I omit something in the code or is something wrong in pop() method?

Upvotes: 0

Views: 4149

Answers (3)

Joran Beasley
Joran Beasley

Reputation: 113950

you should not modify a list as you iterate it!

try

for _ in range(len(c.b.a.s)):
    c.b.a.s.pop() 

instead

Upvotes: 5

Manny D
Manny D

Reputation: 20714

Just so you know, the problem has nothing to do with your class structure. What's happening is a how you're using pop. Since you're actively modifying the list you're iterating over, the internal index for the current iteration will eventually exceed the actual size of the list, causing the for loop to exit.

If you want to empty a list using pop, you should find out how many times to run pop (ie, size of the list) and run it that many times:

for el in xrange(len(c.b.a.s)):
   c.b.a.s.pop()

Upvotes: 0

mtadd
mtadd

Reputation: 2555

Modifying an iterable object while iterating it using a for loop is usually a bad idea unless you really understand its underlying implementation. Instead, use a looping construct such as the following:

while len(c.b.a.s):
    element = c.b.a.s.pop()
    print element, c.b.a.s

Upvotes: 0

Related Questions