【问题标题】:How can I get folder names that match a substring?如何获取与子字符串匹配的文件夹名称?
【发布时间】:2018-01-25 08:30:29
【问题描述】:

我需要递归查找名称包含子字符串“Bar”的文件夹下的所有路径。在 Python 2.7 中

那是文件夹结构

富 | ------ 道格 | | | - - - - 糖果条 | ---------牛奶吧

我需要获取列表["Foo/Doug/CandyBar", "Foo/MilkBar"]

现在我可以使用 os.walk 和 glob.glob 并编写一堆循环来获取此列表,但我想知道我是否缺少更简单的技术。

【问题讨论】:

  • 你不需要写一堆循环。在这里查看答案:stackoverflow.com/a/2186565/3101082 递归使用glob.glob
  • 尝试编写一些代码并向我们展示,您可能会自己想出一些“Pythonic”的东西!一些提示:尝试使用递归和列表推导。
  • 我已经删除了对“pythonic”的请求,只是因为这可能有点主观,否则这个问题很好。
  • Glob 也只能找到文件夹,见:stackoverflow.com/a/36426997/2305545

标签: python python-2.7


【解决方案1】:

也许使用生成器是个不错的选择

import os
res = (path for path,_,_ in os.walk("path") if "bar" in path)

注意:我使用“/”作为根路径,因为我的系统类似于 unix。如果您在 Windows 上,将“/”替换为“C:\”(或任何您想要的)

优点:

  • 生成器使用的内存少得多,并且在计算时不会“阻塞”系统。

示例:

# returns immediately
res = (path for path,_,_ in os.walk("/") if "bar" in path)

#I have to wait (who knows how much time)
res = [path for path,_,_ in os.walk("/") if "bar" in path]
  • 您可以一次获得一条路径,而只需等待找到下一条“路径”所需的时间

示例:

res = (path for path,_,_ in os.walk("/") if "bar" in path)
# the for starts at no time
for path in res:
    # at each loop I only wait the time needed to compute the next path
    print(path) # see the path printed as it is computed 

res = [path for path,_,_ in os.walk("/") if "bar" in path]
# the for starts only after all paths are computed
for path in res:
    # no wait for each loop.
    print(path) # all paths printed at once 
  • 如果您想保留“路径”找到的部分,您可以将其存储在列表中,并且只有您感兴趣的“路径”(内存使用量更少)

示例:

res = (path for path,_,_ in os.walk("/") if "bar" in path)
path_store = []
for path in res:
    # I'm only interested in paths having odd length
    # at the end of the loop I will use only needed memory
    if(len(path)%2==1):
        path_store.append(path)
  • 如果您已经完成并且您对寻找更多“路径”不感兴趣,您可以随时停止,从而节省所有未计算路径所需的时间

示例:

res = (path for path,_,_ in os.walk("/") if "bar" in path)
path_store = []
count = 10
for path in res:
    # I'm only interested in paths having odd length
    if(len(path)%2==1):
        count -= 1
        path_store.append(path)
        # I'm only interested in the first 10 paths.
        # Using generator I waited only for the computation of those 10 paths.
        # Using list you will always wait for the computation for all paths
        if( count <= 0 ):
            break

缺点:

  • 您不能将索引与生成器一起使用。您只能获得下一项。

  • 如果您想要一个同时包含所有路径的列表,则必须将其转换为列表(因此最好使用列表推导式)

  • 生成器是单向前进(获取下一个元素后不能返回)

  • 如果你想保留一些“路径”,你必须将它存储在某个地方(如列表),否则它会丢失

在代码中 path 在每次迭代中都会丢失。 在循环结束时,res 已用尽,不再可用。 我必须将我感兴趣的路径存储在列表 path_store 中。

path_store = []
for path in res:
    # I'm only interested in paths having odd length
    if(len(path)%2==1):
        path_store.append(path)
path = next(res) # Error StopIteration

【讨论】:

    【解决方案2】:

    试试这个:

    import os
    [x for x, _, _ in os.walk("path") if "bar" in x and os.path.isdir(x)]
    

    【讨论】:

    • 如果您将其解压缩为r, _, _ 并丢弃第二个和第三个参数,您可以使其更简洁。然后,你只需要if "bar" in r
    • 对不起,_ 是做什么的?
    • 这表示您只想要参数的一个子集而丢弃其余的。
    • 哦,我明白了。所以它只允许你解包一些参数。
    • OP 的问题标题表明他们只想查找文件夹。如果确实如此,请使用os.path.isdir() 来满足:[x[0] for x in os.walk("path") if "bar" in x[0] and os.path.isdir(x[0])]
    猜你喜欢
    • 1970-01-01
    • 2019-05-10
    • 2021-12-23
    • 1970-01-01
    • 2018-10-06
    • 2018-04-10
    • 2019-01-27
    • 1970-01-01
    • 2017-08-16
    相关资源
    最近更新 更多