ログ ファイルがあり、ファイルの各行の最後に次の文字列があります
Line:#
。#
は行番号です。
# を取得して、前の行の番号と比較しようとしています。Pythonでそれを行う最良の方法は何でしょうか?
str.split
簡単に思えるので、おそらく使用します:
with open('logfile.log') as fin:
numbers = [ int(line.split(':')[-1]) for line in fin ]
zip
これで、ある数値を次の数値と比較するために使用できます。
for num1,num2 in zip(numbers,numbers[1:]):
compare(num1,num2) #do comparison here.
もちろん、これは怠け者ではありません (実際には一度に 2 つしか必要ない場合でも、一度にすべての行番号をファイルに格納します)。そのため、ファイルがHUGEの場合、多くのメモリを消費する可能性があります。ただし、遅延させるのは難しくありません。
def elem_with_next(iterable):
ii = iter(iterable)
prev = next(ii)
for here in ii:
yield prev,here
prev = here
with open('logfile.log') as fin:
numbers = ( int(line.split(':')[-1]) for line in fin )
for num1,num2 in elem_with_next(numbers):
compare(num1,num2)
文字列を分割するのに便利なものがないことを前提としています。つまり、正規表現の方が理にかなっている可能性があります。つまり、ログ ファイルの行が次のように構成されている場合です。
date: 1-15-2013, error: mildly_annoying, line: 121
date: 1-16-2013, error: err_something_bad, line: 123
line.split('#')
そうすると、提案されているようにas mgilsonを使用できなくなりますが、常にコロンがある場合は機能するline.split(':')
可能性があります。いずれにせよ、正規表現のソリューションは次のようになります。
import re
numbers = []
for line in log:
digit_match = re.search("(\d+)$", line)
if digit_match is not None:
numbers.append(int(digit_match.group(1)))
ここで、式"(\d+)$"
はいくつかの桁数に一致し、次に行末に一致します。返された一致オブジェクトのメソッドで数字を抽出し、group(1)
行番号のリストに追加します。
「Line: #」が常にログの最後に来るかどうか確信が持てない場合は、上記で使用した正規表現"Line:\s*(\d+)"
を、文字列「Line:」をチェックしてからいくつか (または No) をチェックするようなものに置き換えることができます。空白、そして任意の桁数。