0

私はメトリックを収集する python スクリプトを書いています。

  • collected、辞書として保存されたすべてのメッセージを含むリスト
  • denied_metrics、コンパイルされたすべての正規表現を含むリスト

collected[i]['service']の少なくとも 1 つの正規表現に一致するメッセージの転送を禁止できるようにしたいと考えていますdenied_metrics

リスト内包表記とを使用して目標を達成しようとしてfilterいましたが、そのようにすることはできませんでした。

実際のソリューション

メッセージの構造は次のとおりです。

msg = { 
  'service': 'foo', 
  'metric':    1.0,
  'denied':  False 
}

collected実際には、次のようにすべてのメッセージをフィルタリングしています

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 ]

質問

リスト内包表記とまたはの組み合わせだけを使用して、許可されたメッセージのリストを取得する (より良い?) 方法はありますか?filterreduce


編集

@eyquemが彼の回答で提案したように、問題にアプローチする可能性については知りませんでした。

4

2 に答える 2

2

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}]

もちろん、正規表現に依存するかどうかにsearch関係なく。match[ところで、「denied_services」の方がいい名前ではないでしょうか?]

于 2013-05-23T19:09:28.910 に答える
1

XY 問題があります。

反復中にリストの要素を削除するには、次の 2 つの方法があります。

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']

.

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

最後のコードreversed()では反復子が返され、新しいリストを作成する必要はありません。

于 2013-05-23T19:31:41.950 に答える