【问题标题】:Logic for finding and excluding multiple matches from a list从列表中查找和排除多个匹配项的逻辑
【发布时间】:2012-05-22 13:12:12
【问题描述】:

我需要将列表的内容与给定的模式匹配,并形成另一个列表,该列表将包含除匹配项之外的所有内容。意思是,我正在尝试制作一个排除列表。

现在有了一个模式匹配,这很容易。但对于更多的,它变得棘手。

让我们看一个例子:

Lmain=[arc123, arc234,xyz111,xyz222,ppp999,ppp888]

for count in range(len[Lmain]):

    if Pattern matches Lmain[i]:
              Pass
    else:result.append(Lmain[i])

现在让我们说 pattern = arc ,我的结果将是

result = [xyz111,xyz222,ppp999,ppp888]

这只是一个逻辑,我将使用常规 expr 来查找匹配项。

现在如果我们有 2 种模式,那么在循环中使用上述逻辑:

Pattern=['arc','xyz']

for pat in Pattern:
      if pat matches Lmain[i]:
          Pass
      else:result.append(Lmain[i])

这会给我们错误的结果

result = [xyz111,xyz222,ppp999,ppp888,arc123,arc234,ppp999,ppp888]

所以,你可以看到上面的逻辑是行不通的。

我的计划:

首先我们找到第一个 Pattern 的排除列表,它会给我们结果:

result = [xyz111,xyz222,ppp999,ppp888]

对于第二种模式,我们需要查看上面的结果。

if Pattern matches Result[i]:
      Pass
else:result_final.append(Result[i])

我认为我们需要使用递归来实现上述逻辑。现在我们该怎么做呢? 我们也不知道用户要输入的模式数量。它可以是一个或多个。

任何人有任何逻辑想法,然后请分享。

【问题讨论】:

  • 你的例子可以使用真正的python代码吗?

标签: python logic


【解决方案1】:

使用列表推导和生成器表达式,跳过构建排除列表的中间步骤,只构建最终列表:

>>> import re
>>> Lmain=['arc123', 'arc234', 'xyz111', 'xyz222','ppp999','ppp888']
>>> Pattern=['arc','xyz']
>>> [x for x in Lmain if not any(re.search(y, x) for y in Pattern)]
['ppp999', 'ppp888']

【讨论】:

    【解决方案2】:
    for item in lst:
        if all(pat not in item for pat in patterns):
            exclude_list.append(item)
    

    in 替换为更适合您的情况(例如item.startswith(pat)

    如果匹配的比不匹配的多,应该先找到匹配的,然后再排除:

    matches = [x for x in lst if any(x.startswith(p) for p in patterns)]
    exclude_list = list(set(lst).difference(matches))
    

    另一个(可能是最快的)选项是使用正则表达式(这里结合filter):

    import re
    expr = '^(?!%s)' % '|'.join(patterns)
    exclude_list = filter(re.compile(expr).search, lst)
    

    【讨论】:

    • +1,也可以单行:exclude_list = [item for item in lst if all(pat not in item for pat in patterns)]
    • @eumiro,是的,这是 Wooble 写的,但我发现在这种情况下,compr 的可读性较差。
    【解决方案3】:
    matched = False
    for pat in Pattern:
        if pat patches Lmain[i]:
            matched = True
            break;
    if matched:
        Pass
    else:
        result.append(Lmain[i])
    

    【讨论】:

      猜你喜欢
      • 2017-07-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-31
      • 2022-10-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多