【问题标题】:How can I iterate over files in a given directory?如何遍历给定目录中的文件?
【发布时间】:2022-01-02 11:44:32
【问题描述】:

我需要遍历给定目录中的所有.asm 文件并对它们执行一些操作。

如何有效地做到这一点?

【问题讨论】:

    标签: python iterator directory


    【解决方案1】:

    上述答案的 Python 3.6 版本,使用 os - 假设您在名为 directory_in_str 的变量中将目录路径作为 str 对象:

    import os
    
    directory = os.fsencode(directory_in_str)
        
    for file in os.listdir(directory):
         filename = os.fsdecode(file)
         if filename.endswith(".asm") or filename.endswith(".py"): 
             # print(os.path.join(directory, filename))
             continue
         else:
             continue
    

    或者递归,使用pathlib:

    from pathlib import Path
    
    pathlist = Path(directory_in_str).glob('**/*.asm')
    for path in pathlist:
         # because path is object not string
         path_in_str = str(path)
         # print(path_in_str)
    
    • 使用rglobglob('**/*.asm') 替换为rglob('*.asm')
      • 这就像调用Path.glob() 并在给定的相对模式前添加'**/'
    from pathlib import Path
    
    pathlist = Path(directory_in_str).rglob('*.asm')
    for path in pathlist:
         # because path is object not string
         path_in_str = str(path)
         # print(path_in_str)
    

    原答案:

    import os
    
    for filename in os.listdir("/path/to/dir/"):
        if filename.endswith(".asm") or filename.endswith(".py"): 
             # print(os.path.join(directory, filename))
            continue
        else:
            continue
    

    【讨论】:

    • 请注意,在 Python 3.6 中,目录应该以字节为单位,然后 listdir 会以字节数据类型吐出文件名列表,因此您不能直接在其上运行 endswith。此代码块应更改为directory = os.fsencode(directory_in_str) for file in os.listdir(directory): filename = os.fsdecode(file) if filename.endswith(".asm") or filename.endswith(".py"): # print(os.path.join(directory, filename)) continue else: continue
    • print(os.path.join(directory, filename)) 需要更改为 print(os.path.join(directory_in_str, filename)) 才能在 python 3.6 中工作
    • 如果您在 2017 年或以后看到这个,现在可以使用 os.scandir(dir_str) 并且使用起来更加简洁。不需要 fsencode。 for entry in os.scandir(path): print(entry.path)
    • 首选if filename.endswith((".asm", ".py")): 优于if filename.endswith(".asm") or filename.endswith(".py"):
    • Python 3.7+ :删除行 directory = os.fsencode(directory_in_str) 如此处所述:stackoverflow.com/questions/48729364/…
    【解决方案2】:

    这将遍历所有后代文件,而不仅仅是目录的直接子文件:

    import os
    
    for subdir, dirs, files in os.walk(rootdir):
        for file in files:
            #print os.path.join(subdir, file)
            filepath = subdir + os.sep + file
    
            if filepath.endswith(".asm"):
                print (filepath)
    

    【讨论】:

    【解决方案3】:

    您可以尝试使用glob 模块:

    import glob
    
    for filepath in glob.iglob('my_dir/*.asm'):
        print(filepath)
    

    从 Python 3.5 开始,您也可以搜索子目录:

    glob.glob('**/*.txt', recursive=True) # => ['2.txt', 'sub/3.txt']
    

    来自文档:

    glob 模块根据 Unix shell 使用的规则查找与指定模式匹配的所有路径名,尽管结果以任意顺序返回。不进行波浪号扩展,但 *、? 和用 [] 表示的字符范围将正确匹配。

    【讨论】:

      【解决方案4】:

      从 Python 3.5 开始,使用 os.scandir() 和速度提高 2-20 倍 (source),事情变得容易得多:

      with os.scandir(path) as it:
          for entry in it:
              if entry.name.endswith(".asm") and entry.is_file():
                  print(entry.name, entry.path)
      

      使用 scandir() 代替 listdir() 可以显着增加 还需要文件类型或文件属性的代码的性能 信息,因为 os.DirEntry 对象会在以下情况下公开此信息 操作系统在扫描目录时提供它。全部 os.DirEntry 方法可以执行系统调用,但 is_dir() 和 is_file() 通常只需要对符号链接进行系统调用; os.DirEntry.stat() 在 Unix 上总是需要系统调用,但只有 Windows 上的符号链接需要一个。

      【讨论】:

      • entry 是一个posix.DirEntry 类型,带有许多方便的方法,例如entry.is_dir()is_file()is_symlink()
      • @tejasvi88 否则需要显式调用scandir.close() 来关闭迭代器并释放获取的资源
      【解决方案5】:

      Python 3.4 及更高版本在标准库中提供pathlib。你可以这样做:

      from pathlib import Path
      
      asm_pths = [pth for pth in Path.cwd().iterdir()
                  if pth.suffix == '.asm']
      

      或者如果你不喜欢列表推导:

      asm_paths = []
      for pth in Path.cwd().iterdir():
          if pth.suffix == '.asm':
              asm_pths.append(pth)
      

      Path 对象可以轻松转换为字符串。

      【讨论】:

        【解决方案6】:

        以下是我在 Python 中遍历文件的方法:

        import os
        
        path = 'the/name/of/your/path'
        
        folder = os.fsencode(path)
        
        filenames = []
        
        for file in os.listdir(folder):
            filename = os.fsdecode(file)
            if filename.endswith( ('.jpeg', '.png', '.gif') ): # whatever file types you're using...
                filenames.append(filename)
        
        filenames.sort() # now you have the filenames and can do something with them
        

        这些技术都不保证任何迭代顺序

        是的,超级不可预测。请注意,我对文件名进行了排序,如果文件的顺序很重要,即对于视频帧或时间相关的数据收集,这很重要。不过请务必在文件名中添加索引!

        【讨论】:

        • 并非总是排序... im1,im10,im11..., im2... 其他有用的方法。 from pkg_resources import parse_versionfilenames.sort(key=parse_version) 做到了。
        【解决方案7】:

        您可以使用glob 来引用目录和列表:

        import glob
        import os
        
        #to get the current working directory name
        cwd = os.getcwd()
        #Load the images from images folder.
        for f in glob.glob('images\*.jpg'):   
            dir_name = get_dir_name(f)
            image_file_name = dir_name + '.jpg'
            #To print the file name with path (path will be in string)
            print (image_file_name)
        

        要获取数组中所有目录的列表,您可以使用os

        os.listdir(directory)
        

        【讨论】:

          【解决方案8】:

          我对这个实现还不是很满意,我想要一个自定义构造函数来执行DirectoryIndex._make(next(os.walk(input_path))),这样你就可以传递你想要的文件列表的路径。欢迎编辑!

          import collections
          import os
          
          DirectoryIndex = collections.namedtuple('DirectoryIndex', ['root', 'dirs', 'files'])
          
          for file_name in DirectoryIndex(*next(os.walk('.'))).files:
              file_path = os.path.join(path, file_name)
          

          【讨论】:

            【解决方案9】:

            我非常喜欢使用 os 库中内置的 scandir 指令。这是一个工作示例:

            import os
            
            i = 0
            with os.scandir('/usr/local/bin') as root_dir:
                for path in root_dir:
                    if path.is_file():
                        i += 1
                        print(f"Full path is: {path} and just the name is: {path.name}")
            print(f"{i} files scanned successfully.")
            

            【讨论】:

            • 重复答案
            猜你喜欢
            • 2017-06-22
            • 1970-01-01
            • 2014-06-17
            • 2011-06-22
            • 1970-01-01
            相关资源
            最近更新 更多