私のコードの一般的なパターンは、「特定の要素が見つかるまでリストを検索し、その前後にある要素を調べる」です。
例として、重要なイベントがアスタリスクでマークされているログ ファイルを調べて、重要なイベントのコンテキストを引き出したいと思うかもしれません。
次の例では、ハイパードライブが爆発した理由を知りたい:
Spinning up the hyperdrive
Hyperdrive speed 100 rpm
Hyperdrive speed 200 rpm
Hyperdrive lubricant levels low (100 gal.)
* CRITICAL EXISTENCE FAILURE
Hyperdrive exploded
get_item_with_context()
アスタリスクが付いた最初の行を見つけて、その前の行とその次の行を表示できるn
関数が必要ですm
。
私の試みは以下です:
import collections, itertools
def get_item_with_context(predicate, iterable, items_before = 0, items_after = 0):
# Searches through the list of `items` until an item matching `predicate` is found.
# Then return that item.
# If no item matching predicate is found, return None.
# Optionally, also return up to `items_before` items preceding the target, and
# `items after` items after the target.
#
# Note:
d = collections.deque (maxlen = items_before + 1 + items_after)
iter1 = iterable.__iter__()
iter2 = itertools.takewhile(lambda x: not(predicate(x)), iter1)
d.extend(iter2)
# zero-length input, or no matching item
if len(d) == 0 or not(predicate(d[-1])):
return None
# get context after match:
try:
for i in xrange(items_after):
d.append(iter1.next())
except StopIteration:
pass
if ( items_before == 0 and items_after == 0):
return d[0]
else:
return list(d)
使用法は次のようにする必要があります。
>>> get_item_with_context(lambda x: x == 3, [1,2,3,4,5,6],
items_before = 1, items_after = 1)
[2, 3, 4]
これに関する問題:
- を使用して、実際に一致が見つかったことを確認するためのチェックは
not(predicate(d[-1]))
、何らかの理由で機能しません。常に false を返します。 items_after
一致する項目が見つかった後にリスト内の項目が少ない場合、結果はごみです。- 他のエッジケース?
これを機能させる/より堅牢にする方法についてアドバイスをお願いできますか? または、車輪の再発明をしている場合は、それも遠慮なく教えてください。