2

I wrote a program of python as below:

from os import listdir 
def getfilename():
    namelist=listdir(".")
    print namelist
    for name in namelist:
        print name
        if 'lp' in name:
            namelist.remove(name)
    return namelist

when I run it on the command line and print the return value, the result is :

['all_test1.list', 'all_test2.list', 'lp.py', 'lp.pyc', 'lp.test', 'straightrnd_test1.list', 'straightrnd_test2.list', 'straightrnd_train.list']
all_test1.list
all_test2.list
lp.py
lp.test
straightrnd_test2.list
straightrnd_train.list
['all_test1.list', 'all_test2.list', 'lp.pyc', 'straightrnd_test1.list', 'straightrnd_test2.list', 'straightrnd_train.list']  

The file 'lp.pyc' lost in for loop, so the return value contains it, I wanna remove it from the list,what should I do? Why the element lost in for loop?

ChaosCosmos
  • 107
  • 8

2 Answers2

2

You are altering the list you are iterating over. Use list comprehensions:

newlist = [x for x in namelist if 'lp' not in x]

zero_dev
  • 613
  • 9
  • 17
1

This question addresses the problem pretty well but in a nutshell:

Even though you don't explicitely loop over the list via the index of the elements, Python sort-of does it for you internally.

It's really as if you wrote something like:

l = listdir(".")
while i < len(l):
    name = l[i]
    if 'lp' in name:
        l.remove(name)
        # Now evaluating l[i] yields another element, even though i was not incremented !

    i = i + 1

So when you remove an element during the iteration, it shifts the loop pointer one time too many, hence the problem you are observing.

Note that in your case, you could just write:

from os import listdir 

def getfilename():
    return [x for x in listdir(".") if not 'lp' in x]

Even though the name getfilename is a bit weird, given that it actually returns a list... but that's another issue.

Community
  • 1
  • 1
ereOn
  • 53,676
  • 39
  • 161
  • 238