0

试图创建一个包含多个扩展名的文件列表以进行迭代。大多数关于堆栈溢出的答案都涉及使用 lambda 进行过滤,但我不确定在这种情况下如何工作(只是因为迭代的设置方式)。到目前为止我有

import fnmatch

excluded = ['*.py', '*.py~']

fileNames = []

for fileName in os.listdir('.'):
    fileNames.append(fileName)
    print fileNames

for p in excluded:
    if fnmatch.fnmatch(fileName, p):
        fileNames.remove(fileName)
        print fileNames

显然问题是 list.remove 只删除第一个实例而不是所有实例。你认为解决这个问题最有效的方法是什么?

谢谢!

4

3 回答 3

4

使用列表理解)):

filtered = [x for x in os.listdir('.') if not any(fnmatch.fnmatch(x, p) for p in excluded)]

或者,使用正则表达式的更紧凑的代码:

filtered = [x for x in os.listdir('.') if not re.search(r'\.py~?$', x)]

或简单地使用endswith

excluded = ('.py', '.py~')
filtered = [x for x in os.listdir('.') if not x.endswith(excluded)]
于 2012-06-01T10:27:37.503 回答
2

使用列表理解

for p in excluded:
    fileNames = [filename for filename in fileNames if not fnmatch.fnmatch(filename, p)]

您也可以使用以下方法更好地做到这一点any()

fileNames = [filename for filename in fileNames if not any(fnmatch.fnmatch(filename, p) for p in excluded)]

请注意,您正在制作的列表是没有意义的,因为os.listdir()无论如何都会返回一个列表,因此您可以这样做fileNames = os.listdir()以获得相同的结果 - 甚至将其放在列表理解中:

fileNames = [filename for filename in os.listdir() if not any(fnmatch.fnmatch(filename, p) for p in excluded)]

如果您想在构建列表时编辑值,您也可以使用列表推导来执行此操作。

另一种选择是fnmatch具有fnmatch.filter().

于 2012-06-01T10:25:36.557 回答
2
def includefilename(fileName):
    for ex in excluded:
        if fnmatch.fnmatch(fileName, ex):
            return False
    return True

fileNames = [fileName for fileName in fileNames if includefilename(fileName)]
于 2012-06-01T10:27:46.693 回答