【问题标题】:Check string includes/does not include values from distinct lists检查字符串包括/不包括来自不同列表的值
【发布时间】:2016-11-09 11:18:48
【问题描述】:
listIncludedFolders = ["Criteria1"]
listExcludedFolders = ["Criteria2"]

for dirpath, dirnames, filenames in os.walk(root):

    proceed = False

    for each in listIncludedFolders:
        if each in dirpath:
            proceed = True

    if proceed == True:
        for each in listExcludedFolders:
            if each in dirpath:
                proceed = False

    if proceed == True:
        print(dirpath)

我正在尝试以更 Python 的方式实现以下代码。使用生成器,我可以设法根据单个列表项进行操作:

if any(dir in dirpath for dir in listIncludedFolders):
    print(dirpath)

...但我无法添加第二个比较。我在下面设法拥有一个附加条件,但我需要遍历附加条件列表:

if any(dir in dirpath for dir in listIncludedFolders if("Criteria2" not in dirpath)):
    print(dirpath)

我怎样才能“干净”地做到这一点?

【问题讨论】:

    标签: python list python-3.x generator os.walk


    【解决方案1】:

    将两个条件与and 运算符与另一个any 调用结合起来:

    if any(each in dirpath for each in listIncludedFolders) and \
            not any(each in dirpath for each in listExcludedFolders):
        print(dirpath)
    

    或与另一个 and 通话(条件否定):

    if any(each in dirpath for each in listIncludedFolders) and \
           all(each not in dirpath for each in listExcludedFolders):
        print(dirpath)
    

    顺便说一句,(... for .. in .. if ..) 是 generator expression,而不是 list comrpehension。

    【讨论】:

      【解决方案2】:

      您可以避免进入一开始就被排除在外的子树。此解决方案也比原始方法更健壮,假设测试子字符串以确定文件夹的包含和排除不是什么意思(您真的要排除名为“Criteria2345”的文件夹吗?)

      for dirpath, dirnames, filenames in os.walk(root):
          if set(dirpath.split(os.path.sep)) & set(listIncludedFolders):
              print(dirpath)
          for ex in [dnam for dnam in dirnames if dnam in listExcludedFolders]:
              dirnames.remove(ex)
      

      但请注意,如果 root 在排除列表中,则在此实现中将被忽略。

      【讨论】:

      • 我不确定我是否遵循您的建议。我看到的结果是使用 os.walk 排除的目录没有被输入。我也明白 os.path.walk 已被弃用,应该避免。我当然不想在目录上浪费时间……
      • 嘿,感谢 os.path.walk 已被弃用的提示。我确信您上面的代码也进入了排除的目录。事实证明,你也可以使用 os.walk 来避免这种情况。我相应地编辑了答案。
      • 谢谢 - 我试过你的代码。它的运行速度比我发布的答案快很多,但它也找到了更多文件夹,而不是我发布的答案中找到的文件夹。可能是因为“if set(dirpath.split(os.path.sep)) & set(listIncludedFolders):”这行。你能解释一下这条线吗?我不确定它在做什么。
      • 左边的表达式是属于dirpath 的所有目录名称的集合。右边的表达式是listIncludedFolders 的元素集合。运算符& 返回两个集合的交集。由于空集的真值是False,因此要打印dirpath,它必须至少包含一个也在“listIncludedFolders”中的目录。
      • 此解决方案比其他解决方案找到更多文件夹的原因肯定是,在此解决方案中,仅排除了包含listExcludedFolders 中的路径元素的dirpaths。在另一个解决方案中,还排除了dirpaths,其子字符串等于listExcludedFolders 中的任何元素。
      【解决方案3】:

      这很好用:

      listIncludedFolders = ["Criteria1"]
      listExcludedFolders = ["Criteria2"]
      
      for dirpath, dirnames, filenames in os.walk(root):
      
          if any(each in dirpath for each in listIncludedFolders) and \
                  not any(each in dirpath for each in listExcludedFolders):
              print(dirpath)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2022-05-27
        • 1970-01-01
        • 2022-01-13
        • 1970-01-01
        • 2020-09-09
        • 2012-10-23
        • 1970-01-01
        相关资源
        最近更新 更多