列出文件夹中的png文件

imj*_*imj 5 python file-io

我正在尝试列出包含其他文件夹的文件夹中的所有png文件.这是我的代码.

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

问题是,最后一个打印显示一些子文件夹(但不是全部)逃脱了剔除......

['aa.png', 'Nouveau dossier - Copie', 'Nouveau dossier - Copie (3)', 'Nouveau dossier - Copie (5)', 'zz.png']
Run Code Online (Sandbox Code Playgroud)

我究竟做错了什么 ?

Ara*_*Fey 13

迭代时不应修改列表.它会导致有趣的事情发生.

最好使用列表理解:

filelist= [file for file in os.listdir('images') if file.endswith('.png')]
Run Code Online (Sandbox Code Playgroud)


Cod*_*all 10

简介:永远不会修改您正在迭代的列表.

相反,迭代副本:

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)
Run Code Online (Sandbox Code Playgroud)

或者,如果您不喜欢制作不必要的副本,则反向迭代(这只有在您可以保证列表中的项目是唯一的时才有效;对于文件系统,这是一个很好的假设):

for fichier in reversed(filelist):
    # do stuff
Run Code Online (Sandbox Code Playgroud)

请注意,您可以使用Python的glob模块来简化:

import glob
print(glob.glob('images/*.png'))
Run Code Online (Sandbox Code Playgroud)

之所以

当您在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))
Run Code Online (Sandbox Code Playgroud)

您可以通过此处打印的内容判断跳过第二个2,l其值为[1, 2, 3].这是因为,只要达到并移除前2,索引就是1(第二个元素).在下一次迭代中,索引是2.在这一点上l == [1,2,3],如此x == 3.如果您运行代码,它可能会比这个解释更明显.