Python:从使用过滤器的列表中删除多个值更加尴尬

时间:2012-06-01 10:23:18

标签: python

尝试创建具有多个扩展名的文件列表,以便迭代。堆栈溢出的大多数答案都涉及使用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只删除第一个实例而不是所有实例。你认为什么是解决这个问题最有效的方法?

谢谢!

3 个答案:

答案 0 :(得分: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)]

答案 1 :(得分:2)

使用list comprehension

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()即可获得相同的结果 - 或者甚至将其放入列表解析中:< / p>

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

如果要在构建列表时编辑值,也可以使用列表推导进行编辑。

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

答案 2 :(得分: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)]