перечисление png-файлов в папке

Я пытаюсь составить список всех png-файлов в папке, содержащей другие папки. Вот мой код.

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

проблема в том, что последний отпечаток показывает, что некоторые из подпапок (но не все) избежали отбраковки …

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

Что я делаю не так ?

Резюме: Никогда, никогда, никогда не изменяйте список, который вы повторяете.

Вместо этого перебирайте копию:

 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) 

Или, если вам не нравится делать ненужные копии, итерации в обратном порядке (это будет работать, только если вы можете гарантировать, что элементы в списке уникальны, а для файловой системы это хорошее предположение):

 for fichier in reversed(filelist): # do stuff 

Обратите внимание, что вы можете использовать модуль glob Python для упрощения этого:

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

Причина почему

Когда вы перебираете список в Python, за кулисами Python фактически выполняет итерацию по индексам списка. Вы можете видеть, что это огромная проблема, когда вы фактически удаляете элементы:

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

Вы можете сказать, что напечатано здесь, что вторая 2 пропущена, и что l имеет значение [1, 2, 3] . Это связано с тем, что, когда первый и 2 достигнут и удалены, индекс равен 1 (второй элемент). На следующей итерации индекс равен 2 . На этом этапе l == [1,2,3] , поэтому x == 3 . Если вы запустите код, это, вероятно, будет более очевидным, чем это объяснение.

Вы не должны изменять списки, итерации по ним. Это вызывает забавные вещи.

Лучше всего использовать понимание списка:

 filelist= [file for file in os.listdir('images') if file.endswith('.png')]