Python 按正则表达式匹配筛选词典列表
我正在编写一个收集指标的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
,包含所有消息的列表,存储为字典已收集
,包含所有已编译正则表达式的列表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问题