Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

listing png files in folder [duplicate]

Tags:

python

file-io

I'm trying to make a list of all png files in a folder that contains other folders. Here's my code.

import os
filelist=os.listdir('images')
for fichier in filelist:
    if not(fichier.endswith(".png")):
        filelist.remove(fichier)
print(filelist)

problem is, that last print shows that some of the subfolders (but not all) escaped the culling...

['aa.png', 'Nouveau dossier - Copie', 'Nouveau dossier - Copie (3)', 'Nouveau dossier - Copie (5)', 'zz.png']

What am I doing wrong ?

like image 447
imj Avatar asked Dec 21 '14 20:12

imj


1 Answers

Summary: Never, ever, ever modify the list that you are iterating over.

Instead, iterate over a copy:

import os
filelist=os.listdir('images')
for fichier in filelist[:]: # filelist[:] makes a copy of filelist.
    if not(fichier.endswith(".png")):
        filelist.remove(fichier)
print(filelist)

Or if you don't like to make unnecessary copies, iterate in reverse (this will only work if you can guarantee that the items in the list are unique; for a file system this is a good assumption):

for fichier in reversed(filelist):
    # do stuff

Note that you can use Python's glob module to simplify this:

import glob
print(glob.glob('images/*.png'))

The reason why

When you iterate over a list in Python, behind the scenes Python is actually iterating over the indices of the list. You can see that this is a huge problem whenever you actually remove the items:

l = [1, 2, 2, 3]:
for x in l:
    if x%2 == 0:
        l.remove(x)
    print('x == {}'.format(x))
print('l == {}'.format(l))

You can tell by what is printed here that the second 2 is skipped, and that l has a value of [1, 2, 3]. This is because, whenever the first 2 is reached and removed, the index is 1 (the second element). On the next iteration, the index is 2. At this point, l == [1,2,3], so x == 3. If you run the code, it will probably be more obvious than this explanation.

like image 108
Cody Piersall Avatar answered Oct 12 '22 12:10

Cody Piersall