【问题标题】:listing png files in folder [duplicate]列出文件夹中的png文件[重复]
【发布时间】:2015-02-19 23:51:06
【问题描述】:

我正在尝试列出包含其他文件夹的文件夹中的所有 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']

我做错了什么?

【问题讨论】:

标签: python file-io


【解决方案1】:

总结:永远,永远,永远修改您正在迭代的列表。

相反,迭代一个副本:

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

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

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。如果你运行代码,它可能会比这个解释更明显。

【讨论】:

  • 谢谢,这解释了为什么它不起作用。应该看过。
【解决方案2】:

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

最好使用列表推导:

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

【讨论】:

  • 同样的概念可以应用到最初的方法中,只是替换了remove-step。然而,这更像是pythonic
  • 是的,我总是忘记你可以在 python 中做到这一点。
猜你喜欢
  • 1970-01-01
  • 2013-12-11
  • 1970-01-01
  • 2013-06-06
  • 2012-09-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多