【问题标题】:find matching substring in a list with multiple condition在具有多个条件的列表中查找匹配的子字符串
【发布时间】:2021-12-27 08:02:04
【问题描述】:

我有多个列表。

item1 = [
    "4bff652c-a589-4cb0-b28f-0745e199ae88-ppp.json",
    "40e10f09-9d53-4891-a4d4-d2885e5492af-vvv.json",
    "065aa522-a458-44d6-9894-7e928d422c35-a.json",
    "5ba3fcb2-8fae-4847-a631-9d57acb6885c.json"
]

item2 = [
    "fa28f1ba-5532-4ff8-945d-70f5b57a7733-ppp.json",
    "ee65f5b5-1333-47f3-8eca-49b63fa35a62-a.json",
    "9bc518d8-84b4-4032-9ed8-4bb78559a9a0.json",
    "a20bc0c3-ff61-4df5-90c5-695c7614222e-b.json"
]

item3 = [
    "6e1cb404-9494-4e2d-a4c7-16c62bf440ce-vvv.json",
    "a3b3e94c-fe69-4304-8129-2137a6407479-a.json"
]

我想查找以上列表中是否有以 -ppp.json 和 -vvv.json 结尾的项目。

从上面的例子中,正确答案是item1。

我试过了

for i in item1:
  if i.endswith("-ppp.json") and i.endswith("-vvv.json"):
     print(i)
     #do some opertion

但是上面的代码不起作用。

提前致谢。

【问题讨论】:

    标签: python json


    【解决方案1】:

    这是一个简单的解决方案。首先,您检查是否有 vvvppp 项目。然后,如果他们是,你做你的操作

    item1 = ["4bff652c-a589-4cb0-b28f-0745e199ae88-ppp.json",
    "40e10f09-9d53-4891-a4d4-d2885e5492af-vvv.json",
    "065aa522-a458-44d6-9894-7e928d422c35-a.json",
    "5ba3fcb2-8fae-4847-a631-9d57acb6885c.json"]
    
    
    item1_contains_ppp = False
    item1_contains_vvv = False
    
    for i in item1:
        if i.endswith("-ppp.json"):
            item1_contains_ppp = True
            
        if i.endswith("-vvv.json"):
            item1_contains_vvv = True
            
    if item1_contains_vvv and item1_contains_ppp:
        ...
        #do some operation
    
    

    【讨论】:

      【解决方案2】:

      对于每个列表,您可以尝试:

      ppp = 0
      vvv = 0
      
      for item in lst:
          if re.search(r'-ppp\.json$', item):
              ppp = 1
          if re.search(r'-vvv\.json$', item):
              vvv = 1
      
      if ppp + vvv == 2:
          print("List matches")
      else:
          print("List does not match")
      

      此方法使用两个单独的变量来跟踪列表条目是否以-ppp.json-vvv.json 结尾。如果两者都看过,则列表报告为通过,否则报告为失败。

      【讨论】:

        【解决方案3】:

        类似以下的方法会起作用:

        def check_endings(items):
            return all(any(l) for l in zip(*[(bool(re.match(".*-ppp.json$", i)), bool(re.match(".*-vvv.json$", i))) for i in items]))
        
        print(check_endings(item1))
        print(check_endings(item2))
        print(check_endings(item3))
        

        输出

        True
        False
        False
        

        本质上:

        • 您通过列表理解遍历列表的每个元素
        • 创建了一个由两个布尔值组成的元组列表。例如,对于item1,您会得到
        [(True, False), (False, True), (False, False), (False, False)]
        

        假设第一个元素以-ppp.json 结尾,第二个元素以-vvv.json 结尾。

        • 使用zip(*转置元组列表,得到
        [(True, False, False, False), (False, True, False, False)]
        

        每个向量分别告诉您是否有-ppp.json-vvv.json

        • 使用any 检查每个列表中是否至少有一个True;最后,使用 all 验证两个列表都有 True

        必须注意,列表推导中的bool 强制转换不是必需的(Matchtrue-ish 元素),但我用它来帮助解释:

        def check_endings(items):
            return all(any(l) for l in zip(*[(re.match(".*-ppp.json$", i), re.match(".*-vvv.json$", i)) for i in items]))
        

        另外,必须强调的是,您可能不需要检查所有元素来得出特定列表满足您的条件的结论:例如,您知道列表item1 在2 个元素之后是好的。在这种情况下:

        def check_endings(items):
            res = [False, False]
            for item in items:
                if re.match(".*-ppp.json$", item):
                    res[0] = True
                elif  re.match(".*-vvv.json$", item):
                    res[1] = True
                if all(res):
                    return True
            return False
        

        这对于非常大的列表可能会有所不同 - 请注意,if all(res) 在循环内部

        【讨论】:

          猜你喜欢
          • 2018-12-07
          • 1970-01-01
          • 2017-10-21
          • 1970-01-01
          • 1970-01-01
          • 2017-07-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多