在Python中删除具有不同名称的文件

时间:2022-09-01 23:17:52

I am trying to delete several files within a directory.

我试图删除目录中的几个文件。

So far I have that code:

到目前为止,我有这个代码:

   for filename in glob.glob("buffer*" ):
        os.remove(filename) 
    for filename in glob.glob("grid*" ):
        os.remove(filename)
    for filename in glob.glob("OSMroads*" ):
        os.remove(filename)
    for filename in glob.glob("newCostSurface*" ):
        os.remove(filename)
    for filename in glob.glob("standsLine*" ):
        os.remove(filename)
    for filename in glob.glob("standsReprojected*" ):
        os.remove(filename)

Is there a way to do this more efficient?

有没有办法更有效率地做到这一点?

2 个解决方案

#1


4  

Doing 6 separate glob calls will of course iterate the directory object 6 times.

当然,执行6次单独的glob调用将迭代目录对象6次。

Fortunately, on almost any platform, it'll probably end up being cached after the first time. Unless your directory is absolutely gigantic, this won't be a noticeable problem.

幸运的是,在几乎任何平台上,它可能最终会在第一次被缓存之后。除非您的目录绝对是巨大的,否则这不会是一个明显的问题。

But since you explicitly asked about efficiency, you can obviously iterate once and filter the results. The easiest way to do this is with fnmatch. All that glob is doing is calling listdir and then fnmatch on each result; you can do the same thing with multiple fnmatch calls:

但是,由于您明确询问了效率,您显然可以迭代一次并过滤结果。最简单的方法是使用fnmatch。 glob所做的就是调用listdir然后对每个结果进行fnmatch;你可以用多个fnmatch调用做同样的事情:

for filename in os.listdir('.'):
    if fnmatch.fnmatch(filename, 'buffer*'):
        os.remove(filename)
    # etc.

And of course you can simplify this in exactly the same way partofthething simplified your existing code:

当然,您可以使用简化现有代码的方式简化此操作:

for filename in os.listdir('.'):
    for pattern in ['buffer*', 'grid*', 'OSMroads*',
                    'newCostSurface*','standsLine*', 'standsReprojected*']:
        if fnmatch.fnmatch(filename, pattern):
            os.remove(filename)

Or:

要么:

for filename in os.listdir('.'):
    if any(fnmatch.fnmatch(filename, pattern)
           for pattern in ['buffer*', 'grid*', 'OSMroads*',
                           'newCostSurface*','standsLine*', 'standsReprojected*']):
        os.remove(filename)

If you really need to squeeze out another tiny fraction of a percent performance, you can use fnmatch.translate to convert each pattern to a regexp, then merge the regexps into an alternation, and compile it, and then apply that regexp object to each filename. But the CPU time for fnmatch compared to the I/O time for reading the directory objects is probably so small the improvement wouldn't even be measurable.

如果你真的需要挤出一小部分性能,你可以使用fnmatch.translate将每个模式转换为正则表达式,然后将正则表达式合并为一个替换,并编译它,然后将该正则表达式对象应用于每个文件名。但是,与读取目录对象的I / O时间相比,fnmatch的CPU时间可能很小,甚至无法测量。

#2


4  

I like using lists so I don't repeat code, like this:

我喜欢使用列表,所以我不重复代码,像这样:

for pattern in ['buffer*','grid*','OSMroads*','newCostSurface*','standsLine*'
                'standsReprojected*']:
    for filename in glob.glob(pattern):
        os.remove(filename)

#1


4  

Doing 6 separate glob calls will of course iterate the directory object 6 times.

当然,执行6次单独的glob调用将迭代目录对象6次。

Fortunately, on almost any platform, it'll probably end up being cached after the first time. Unless your directory is absolutely gigantic, this won't be a noticeable problem.

幸运的是,在几乎任何平台上,它可能最终会在第一次被缓存之后。除非您的目录绝对是巨大的,否则这不会是一个明显的问题。

But since you explicitly asked about efficiency, you can obviously iterate once and filter the results. The easiest way to do this is with fnmatch. All that glob is doing is calling listdir and then fnmatch on each result; you can do the same thing with multiple fnmatch calls:

但是,由于您明确询问了效率,您显然可以迭代一次并过滤结果。最简单的方法是使用fnmatch。 glob所做的就是调用listdir然后对每个结果进行fnmatch;你可以用多个fnmatch调用做同样的事情:

for filename in os.listdir('.'):
    if fnmatch.fnmatch(filename, 'buffer*'):
        os.remove(filename)
    # etc.

And of course you can simplify this in exactly the same way partofthething simplified your existing code:

当然,您可以使用简化现有代码的方式简化此操作:

for filename in os.listdir('.'):
    for pattern in ['buffer*', 'grid*', 'OSMroads*',
                    'newCostSurface*','standsLine*', 'standsReprojected*']:
        if fnmatch.fnmatch(filename, pattern):
            os.remove(filename)

Or:

要么:

for filename in os.listdir('.'):
    if any(fnmatch.fnmatch(filename, pattern)
           for pattern in ['buffer*', 'grid*', 'OSMroads*',
                           'newCostSurface*','standsLine*', 'standsReprojected*']):
        os.remove(filename)

If you really need to squeeze out another tiny fraction of a percent performance, you can use fnmatch.translate to convert each pattern to a regexp, then merge the regexps into an alternation, and compile it, and then apply that regexp object to each filename. But the CPU time for fnmatch compared to the I/O time for reading the directory objects is probably so small the improvement wouldn't even be measurable.

如果你真的需要挤出一小部分性能,你可以使用fnmatch.translate将每个模式转换为正则表达式,然后将正则表达式合并为一个替换,并编译它,然后将该正则表达式对象应用于每个文件名。但是,与读取目录对象的I / O时间相比,fnmatch的CPU时间可能很小,甚至无法测量。

#2


4  

I like using lists so I don't repeat code, like this:

我喜欢使用列表,所以我不重复代码,像这样:

for pattern in ['buffer*','grid*','OSMroads*','newCostSurface*','standsLine*'
                'standsReprojected*']:
    for filename in glob.glob(pattern):
        os.remove(filename)