Создание сложной структуры данных путем анализа выходного файла - PullRequest
0 голосов
/ 21 февраля 2012

Я ищу несколько советов о том, как создать структуру данных путем анализа файла.Это список, который у меня есть в моем файле.

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

Мне нужно создать структуру данных, которая должна выглядеть следующим образом:

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

(не удалось опубликовать его из-за ограничений нового пользователя)

Мне удалось получить все фильтры регулярных выражений, чтобы получить то, что нужно, но мне не удалось построить структуру.Идеи?

Ответы [ 3 ]

3 голосов
/ 21 февраля 2012

Теоретически возможно, чтобы pyparsing создавал всю структуру, используя действия разбора, но если вы просто назовете различные поля, как я указал ниже, построение структуры не так уж плохо.И если вы хотите перейти на использование 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']}}
1 голос
/ 21 февраля 2012

Подумайте об использовании dict of dicts.

#!/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 голосов
/ 21 февраля 2012

Ваша структура верхнего уровня позиционная, поэтому это идеальный выбор для списка.Поскольку списки могут содержать произвольные элементы, то с именем tuple идеально подходит.Каждый элемент в кортеже может содержать список со своими элементами.

Итак, ваш код должен выглядеть примерно так:У меня были различные выражения для получения данных, поэтому я не стал добавлять все детали.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...