在目录中查找图像序列 - 比os.walk()更快?

时间:2014-02-13 13:26:57

标签: python traversal

我正在尝试编写一个遍历目录的脚本(与os.walk几乎相同)但不使用os.walk。原因是每个目录都充满了图像序列,os.walk占用了太多时间。

我的目的是收集每个图像序列的文件名...所以目前,只要找到一个序列中的一个奇异图像,我就会脱离循环。如果目录中只有1个图像序列,这可以正常工作,但如果目录中有2个(或更多)图像序列怎么办?这就是我要解开的地方。

这是我到目前为止所做的:

def find_all_ImageSequences(dir):

    for object in os.listdir(dir):
        if os.path.isdir(dir + "\\" + str(object)):
            find_all_ImageSequences(dir + "\\" + str(object))
        else:
            if object.endswith(('.dpx','.jpg','.jpeg','.exr','.tif')):
                Image_Sequences_List.append(dir + "\\" + str(object))
                image_filename = object.split(".")[0]
                extras = [x for x in os.listdir(dir) if x.split(".")[0] != image_filename]
                if extras:
                    "try to take the 1st image and add it to my Image_Sequences_List"
                break

“extras”列表理解将继续查看该目录中的每个对象,即使在找到第二个图像序列之后也是如此。一旦找到下一个图像序列的第一帧,是否可以突破?

我考虑过使用:

if any([x for x in os.listdir(dir) if x.split(".")[0] != image_filename]):
    "do something"

但这似乎反效果,因为我必须再次遍历当前目录以找到下一个序列。

这样做的最佳方式是什么?

非常感谢

2 个答案:

答案 0 :(得分:2)

此代码使用一个集来跟踪已添加的文件名:

def find_all_ImageSequences(dir):
    seen = set()
    for object in os.listdir(dir):
        if os.path.isdir(dir + "\\" + str(object)):
            find_all_ImageSequences(dir + "\\" + str(object))
        else:
            if object.endswith(('.dpx','.jpg','.jpeg','.exr','.tif')):
                image_filename = object.split(".", 1)[0]
                if image_filename not in seen:
                    Image_Sequences_List.append(dir + "\\" + str(object))
                    seen.add(image_filename)

要提高性能,请查看os.walk替代版https://github.com/benhoyt/scandir,声称在Windows上速度约为8-9倍,在Linux和Mac上速度约为2-3倍OS X。

答案 1 :(得分:1)

经过一些调整后,我发现这是最快的解决方案。

def find_all_ImageSequences(dir):

    child_directories = [x for x in os.listdir(dir) if len(x.split(".")) == 1]
    if len(child_directories) >= 1:
        for directory in child_directories:
            if os.path.isdir(dir + "\\" + directory):
                find_all_ImageSequences(dir + "\\" + directory)

    for object in os.listdir(dir):
        if object.endswith(('.dpx','.jpg','.jpeg','.exr','.tif')):
            image_filename = object.split(".")[0]
            Image_Sequences_List.append(dir + "\\" + str(object))
            if any([x for x in os.listdir(dir) if x.split(".")[0] != image_filename and len(x.split(".")) > 1]):
                extras = set([x.split(".")[0] for x in os.listdir(dir) if x.split(".")[0] != image_filename])
                for i in extras:
                    Image_Sequences_List.append(i)
            break

我做了一个快速测试,将此函数与标准的os.walk()进行比较:

  • os.walk()平均花了53秒
  • find_all_ImageSequences()平均耗时5秒

如果没有找到其他图像序列,则此速度主要取决于打开目录。感谢Janne Karila的帮助。使用set()证明非常有用