Python 按正则表达式匹配筛选词典列表

Python 按正则表达式匹配筛选词典列表,python,python-2.7,list-comprehension,Python,Python 2.7,List Comprehension,我正在编写一个收集指标的python脚本,我有: 已收集,包含所有消息的列表,存储为字典 denied\u metrics,包含所有已编译正则表达式的列表 我希望能够禁止转发那些收集的[I]['service']至少与拒绝的\u度量中的一个正则表达式匹配的消息 我试图通过列表理解和过滤来实现我的目标,但我没有做到这一点 实际解决方案 假定消息具有以下结构: msg = { 'service': 'foo', 'metric': 1.0, 'denied': False

我正在编写一个收集指标的python脚本,我有:

  • 已收集
    ,包含所有消息的列表,存储为字典
  • denied\u metrics
    ,包含所有已编译正则表达式的列表
我希望能够禁止转发那些
收集的[I]['service']
至少与
拒绝的\u度量中的一个正则表达式匹配的消息

我试图通过列表理解
过滤
来实现我的目标,但我没有做到这一点

实际解决方案 假定消息具有以下结构:

msg = { 
  'service': 'foo', 
  'metric':    1.0,
  'denied':  False 
}
实际上,我正在过滤所有收集的
消息,如下所示

def filter_denied( denied_metrics, collected ):
  for pattern in denied_metrics:
    for msg in collected
      if pattern.match( msg['service'] ):
        msg['denied'] = True

return [ msg for msg in collected if msg['denied'] is not True ]
问题 是否有一种(更好的?)方法可以仅使用列表理解
过滤器
减少
的组合来获取允许的消息列表


编辑
我不知道有没有可能像他在回答中建议的@eyquem那样处理这个问题。

IIUC,我可能会这样做

allowed = [msg for msg in collected 
           if not any( dm.search(msg['service']) 
                       for dm in denied_metrics) ]
例如:

>>> pprint.pprint(collected)
[{'denied': False, 'metric': 1.0, 'service': 'ab'},
 {'denied': False, 'metric': 1.0, 'service': 'bc'},
 {'denied': False, 'metric': 1.0, 'service': 'ca'},
 {'denied': False, 'metric': 1.0, 'service': 'cb'},
 {'denied': False, 'metric': 1.0, 'service': 'bc'}]
>>> denied_metrics = [re.compile("a"), re.compile("c$")]
>>> allowed = [msg for msg in collected 
               if not any(dm.search(msg['service'])
               for dm in denied_metrics)]
>>> allowed
[{'metric': 1.0, 'service': 'cb', 'denied': False}]

当然,您想要搜索还是匹配取决于您的正则表达式。[顺便说一句,“拒绝服务”不是一个更好的名字吗?]

IIUC,我可能会这样做

allowed = [msg for msg in collected 
           if not any( dm.search(msg['service']) 
                       for dm in denied_metrics) ]
例如:

>>> pprint.pprint(collected)
[{'denied': False, 'metric': 1.0, 'service': 'ab'},
 {'denied': False, 'metric': 1.0, 'service': 'bc'},
 {'denied': False, 'metric': 1.0, 'service': 'ca'},
 {'denied': False, 'metric': 1.0, 'service': 'cb'},
 {'denied': False, 'metric': 1.0, 'service': 'bc'}]
>>> denied_metrics = [re.compile("a"), re.compile("c$")]
>>> allowed = [msg for msg in collected 
               if not any(dm.search(msg['service'])
               for dm in denied_metrics)]
>>> allowed
[{'metric': 1.0, 'service': 'cb', 'denied': False}]
当然,您想要搜索还是匹配取决于您的正则表达式。[顺便说一句,“拒绝服务”不是一个更好的名字吗?]

你有一个

在列表中迭代时,有两种删除列表元素的方法:

li = ['a',12,45,'h',56,'ju',0]
print li
for i in xrange(len(li)-1,-1,-1):
    if isinstance(li[i],int):
        del li[i]
print li
# prints ['a', 'h', 'ju']

在最后一个代码
reversed()
返回一个迭代器,不需要创建新列表。

您有一个新列表

在列表中迭代时,有两种删除列表元素的方法:

li = ['a',12,45,'h',56,'ju',0]
print li
for i in xrange(len(li)-1,-1,-1):
    if isinstance(li[i],int):
        del li[i]
print li
# prints ['a', 'h', 'ju']


在最后一段代码中,
reversed()
返回一个迭代器,无需创建新列表。

“在Python中,在我对collected进行迭代时,如果collected[i]匹配,则无法删除它。”原因是什么?@eyquem并阅读第二条注释,我想确定一下。请看我的答案您不仅应该阅读第二条评论,还应该阅读所有的线程,您将看到John Machin的答案“在Python中,如果在我迭代collected时它匹配,则无法删除collected[i]”,原因是什么?@eyquem并阅读第二条评论我想确定。请看我的答案。你不仅应该阅读第二条评论,还应该阅读所有的线索,你会看到约翰·梅辛的答案。在真实场景中,术语略有不同。谢谢你,太棒了。在真实场景中,术语略有不同。无论如何谢谢你。我不认为这是XY的问题。我明确地要求使用列表理解和/或过滤器来解决问题,我得到了答案。尽管如此,我确实没有注意其他方法,所以我感谢您的有用回答。我认为您选择使用列表理解(尝试解决方案Y),因为您认为无法在列表中迭代删除(真实的X问题)。但是如果你真正需要的是找到一个列表公司,你是对的,没有XY问题,我不认为这是XY问题。我明确地要求使用列表理解和/或过滤器来解决问题,我得到了答案。尽管如此,我确实没有注意其他方法,所以我感谢您的有用回答。我认为您选择使用列表理解(尝试解决方案Y),因为您认为无法在列表中迭代删除(真实的X问题)。但如果你真正的第一需要是找到一个列表公司,你是对的,没有XY问题