我需要将列表的内容与给定的模式匹配,并形成另一个列表,除了匹配之外的所有内容。意思是,我正在尝试制作排除列表。
现在有一个模式匹配,很容易。但是对于更多那个,它变得棘手。
让我们看一个例子:
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])
我认为我们需要使用Recursion来实现上述逻辑。现在我们该怎么做? 此外,我们不知道用户将要进入的模式数量。它可以是一个或多个。
任何人都有任何逻辑思想,请分享。
答案 0 :(得分:5)
使用列表推导和生成器表达式,并跳过构建排除列表的中间步骤,只是构建最终列表:
>>> 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']
答案 1 :(得分:4)
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)
答案 2 :(得分:1)
matched = False
for pat in Pattern:
if pat patches Lmain[i]:
matched = True
break;
if matched:
Pass
else:
result.append(Lmain[i])