2012-02-21 16 views
0

ファイルを解析してデータ構造を作成する方法に関するアドバイスを探しています。 これは私のファイルにあるリストです。私がする必要がどのような出力ファイルを解析して複雑なデータ構造を作成する

'01bpar(2)= 0.23103878E-01 half_life= 0.3000133E+02 relax_time= 0.4328278E+02', 
'01bpar(3)= 0.00000000E+00', 
'02epar(1)= 0.49998963E+02', 
'02epar(2)= 0.23103878E-01 half_life= 0.3000133E+02 relax_time= 0.4328278E+02', 
'02epar(3)= 0.00000000E+00', 
'02epar(4)= 0.17862340E-01 half_life= 0.3880495E+02 relax_time= 0.5598371E+02', 
'02bpar(1)= 0.49998962E+02', 
'02bpar(2)= 0.23103878E-01 half_life= 0.3000133E+02 relax_time= 0.4328278E+02', 

次のようになりchouldデータ構造の構築である。

http://img11.imageshack.us/img11/7645/datastructure.gif

を(新しいユーザー制限のbecouseそれを投稿できませんでし)

私は」私は必要なものを得るためにすべてのregexpフィルタを得ることができましたが、私は構造体を構築することができません。 アイデア?

+4

をあなたは私が構築するのに失敗する」ことで、正確にはどういう意味ですか構造"?あなたは何を試してみることができますか? – unholysampler

+0

私は何をしたのかをはっきりと理解することなく、私が持っている混乱です。あなたがもっと理解している生地回答が提供されていてもそれが貢献すると思うなら、私はそれを投稿します。 – TheMeaningfulEngineer

答えて

1

dictsのdictを使用することを検討してください。

#!/usr/bin/env python 
import re 
import pprint 
raw = """'01bpar(2)= 0.23103878E-01 half_life= 0.3000133E+02 relax_time= 0.4328278E+02', 
'01bpar(3)= 0.00000000E+00', 
'02epar(1)= 0.49998963E+02', 
'02epar(2)= 0.23103878E-01 half_life= 0.3000133E+02 relax_time= 0.4328278E+02', 
'02epar(3)= 0.00000000E+00', 
'02epar(4)= 0.17862340E-01 half_life= 0.3880495E+02 relax_time= 0.5598371E+02', 
'02bpar(1)= 0.49998962E+02', 
'02bpar(2)= 0.23103878E-01 half_life= 0.3000133E+02 relax_time= 0.4328278E+02',""" 

datastruct = {} 
pattern = re.compile(r"""\D(?P<digits>\d+)(?P<field>[eb]par)[^=]+=\D+(?P<number>\d+\.\d+E[+-]\d+)""") 
for line in raw.splitlines(): 
    result = pattern.search(line) 
    parts = result.groupdict() 
    if not parts['digits'] in datastruct: 
     datastruct[parts['digits']] = {'epar':[], 'bpar':[]} 
    datastruct[parts['digits']][parts['field']].append(parts['number']) 

pprint.pprint(datastruct, depth=4) 

が生成されます

{'01': {'bpar': ['0.23103878E-01', '0.00000000E+00'], 'epar': []}, 
 '02': {'bpar': ['0.49998962E+02', '0.23103878E-01'], 
        'epar': ['0.49998963E+02', 
                 '0.23103878E-01', 
                 '0.00000000E+00', 
                 '0.17862340E-01']}} 

改訂版をコメントに照らして:

pattern = re.compile(r"""\D(?P<digits>\d+)(?P<field>[eb]par)[^=]+=\D+(?P<number>\d+\.\d+E[+-]\d+)""") 

default = lambda : dict((('epar',[]), ('bpar',[]))) 
datastruct = defaultdict(default) 

for line in raw.splitlines(): 
    result = pattern.search(line) 
    parts = result.groupdict() 
    datastruct[parts['digits']][parts['field']].append(parts['number']) 

pprint.pprint(datastruct.items()) 

生成:

[('02', 
  {'bpar': ['0.49998962E+02', '0.23103878E-01'], 
   'epar': ['0.49998963E+02', 
            '0.23103878E-01', 
            '0.00000000E+00', 
            '0.17862340E-01']}), 
 ('01', {'bpar': ['0.23103878E-01', '0.00000000E+00'], 'epar': []})] 
+0

'dict.has_key(key)'は 'key in dict'のために廃止されました。ここで使用するパターンは、(collectionsモジュールの)defaultdictを使用するための主要な候補です。 – PaulMcG

+0

これは正しいソリューションを提供していますか? '['02'] ['epar']'の値が正しくないようです。 – PaulMcG

+0

Doh。私はデータ構造にもっと焦点を当てて、それを噛んだ。 –

0

あなたのトップレベルの構造は、位置である、それはですので、完璧な選択肢 リスト。リストは任意のアイテムを保持できるので、named tupleは完璧です。タプルの各項目は、その要素を持つリストを保持できます。

だから、あなたのコードは次の擬似コードのようになります:あなたが言った

from collections import named tuple 
data = [] 
newTuple = namedtuple('stuff', ['epar','bpar']) 
for line in theFile.readlines(): 
    eparVals = regexToGetThemFromString() 
    bparVals = regexToGetThemFromString() 
    t = newTuple(eparVals, bparVals) 
    data.append(t) 

あなたでしすでにファイルをループし、データを取得するためのさまざまな正規表現を持っていたので、私は追加する気にしませんでしたすべての詳細。

3

理論的には、解析アクションを使用して構造全体を作成することは可能ですが、以下のようにさまざまなフィールドに名前を付けるだけで構造を構築することはあまり悪くありません。あなたはRE年代を使用して変換したい場合は、この例では、あなたに物事がどのように見えるかのスタートを与える必要があります:

source = """\ 
'01bpar(2)= 0.23103878E-01 half_life= 0.3000133E+02 relax_time= 0.4328278E+02', 
'01bpar(3)= 0.00000000E+00', 
'02epar(1)= 0.49998963E+02', 
'02epar(2)= 0.23103878E-01 half_life= 0.3000133E+02 relax_time= 0.4328278E+02', 
'02epar(3)= 0.00000000E+00', 
'02epar(4)= 0.17862340E-01 half_life= 0.3880495E+02 relax_time= 0.5598371E+02', 
'02bpar(1)= 0.49998962E+02', 
'02bpar(2)= 0.23103878E-01 half_life= 0.3000133E+02 relax_time= 0.4328278E+02', """ 

from pyparsing import Literal, Regex, Word, alphas, nums, oneOf, OneOrMore, quotedString, removeQuotes 

EQ = Literal('=').suppress() 
scinotationnum = Regex(r'\d\.\d+E[+-]\d+') 
dataname = Word(alphas+'_') 
key = Word(nums,exact=2) + oneOf("bpar epar") 
index = '(' + Word(nums) + ')' 

keyedValue = key + EQ + scinotationnum 

# define an item in the source - suppress values with keys, just want the unkeyed ones 
item = key('key') + index + EQ + OneOrMore(keyedValue.suppress() | scinotationnum)('data') 

# initialize summary structure 
from collections import defaultdict 
results = defaultdict(lambda : {'epar':[], 'bpar':[]}) 

# extract quoted strings from list 
quotedString.setParseAction(removeQuotes) 
for raw in quotedString.searchString(source): 
    parts = item.parseString(raw[0]) 
    num,par = parts.key 
    results[num][par].extend(parts.data) 

# dump out results, or do whatever 
from pprint import pprint 
pprint(dict(results.iteritems())) 

プリント:

{'01': {'bpar': ['0.23103878E-01', '0.00000000E+00'], 'epar': []}, 
'02': {'bpar': ['0.49998962E+02', '0.23103878E-01'], 
     'epar': ['0.49998963E+02', 
       '0.23103878E-01', 
       '0.00000000E+00', 
       '0.17862340E-01']}} 
+0

私は、それがもっとよく知られているので、私は(今までそれとの接触がなかったので)pyparsingを使用しない変形を研究することを選択しました。しかし、私はまだあなたの努力に感謝しています。 – TheMeaningfulEngineer

+0

問題はありませんが、pyparsingはそこにあるツールの1つで、おそらく馴染みのないものを多用しています。人々はまた、プロトタイプを容易に作り出すための方法として、時にはパイピングを使用します(より高いスピード、ほとんどはIFが必要)。spark/ply/yappsに変換されます。 – PaulMcG

関連する問題