连接pyparsing结果

2024-04-27 00:26:34 发布

您现在位置:Python中文网/ 问答频道 /正文

我最近开始使用pyparsing,我坚持以下几点: 有些数据是以列的形式组织的,列的数量未知,另外,这样的部分可以在输入中多次出现。例如,请参见下面的代码

# -*- coding: utf-8 -*-

from pyparsing import *
from decimal import Decimal

def convert_float(a):
    return Decimal(a[0].replace(',','.'))

def convert_int(a):
    return int(a[0])

NL = LineEnd().suppress()

dot = Literal('.')
dates = Combine(Word(nums,exact=2) + dot + Word(nums,exact=2) + dot + Word(nums,exact=4))
day_with_date = Word(alphas,exact=3).suppress() + dates

amount = ( Combine(OneOrMore(Word(nums)) + ',' + Word(nums),adjacent=False) + 
           Optional(Literal('EUR')).suppress() ).setParseAction(convert_float)
number = Word(nums).setParseAction(convert_int)

item_head = OneOrMore(Keyword('Item').suppress() + number)
item_det = Forward()
item_foot = Forward()

def defineColNumber(t):
    nbcols = len(t)#[0])
    item_det << Dict(Group(day_with_date('date') + Group(nbcols*amount)('data')))
    item_foot << Keyword('TOTAL').suppress() + Group(nbcols*amount)

sec = (item_head('it*').setParseAction(defineColNumber) + 
       Group(OneOrMore(item_det))('details*') + 
       item_foot('totals*'))

parser = OneOrMore(
             sec
         )
parser.ignore(NL)

out = """
                             Item 1             Item 2             Item 3
Sat 20.04.2013     3 126 375,00 EUR     115 297,00 EUR      67 830,00 EUR      
Fri 19.04.2013     1 641 019,20 EUR      82 476,00 EUR      48 759,00 EUR      
Thu 18.04.2013       548 481,10 EUR      46 383,00 EUR      29 810,00 EUR      
Wed 17.04.2013       397 396,70 EUR      42 712,00 EUR      26 812,00 EUR 
TOTAL              8 701 732,00 EUR   1 661 563,00 EUR   1 207 176,00 EUR

                             Item 4             Item 5
Sat 20.04.2013       126 375,00 EUR     215 297,00 EUR      
Fri 19.04.2013     2 641 019,20 EUR      32 476,00 EUR      
Thu 18.04.2013       548 481,10 EUR      56 383,00 EUR      
Wed 17.04.2013       397 396,70 EUR      42 712,00 EUR
TOTAL              2 701 732,00 EUR   1 663 563,00 EUR   

"""

p = parser.parseString(out, parseAll=True)
print p.dump()
print p.it
print p.details[0]['18.04.2013'].data[2]
print p.totals

目前,例如p.it看起来像[[1, 2, 3], [4, 5]] 我需要的是[1,2,3,4,5]以及其他部分,因此我可以代替p.details[0]['18.04.2013'].data[2]执行p.details['18.04.2013'].data[2]

我没有主意了-是否可以以某种简单的方式连接结果,或者我需要使用其他函数更改ParseResults

谢谢你的帮助

顺便说一句,这段代码在解析日期、数量等方面有意义吗


Tags: convertdatadefgroupdetailseuritemexact
1条回答
网友
1楼 · 发布于 2024-04-27 00:26:34

这种表格数据的解析是pyparsing编写的原始案例之一。祝贺您在解析一个不平凡的输入文本方面取得了这么大的进步

与其尝试进行任何不自然的分组或诸如此类的操作来扭曲或组合已解析的数据到所需的数据结构中,我只需遍历已解析的结果,并构建一个新的摘要结构,我将其称为summary。我们实际上要将数据累积到这个dict中,它强烈建议在找到新键时使用defaultdict简化摘要的初始化

from collections import defaultdict
summary = defaultdict(dict)

查看p中返回的当前结构,您将获得收集到命名结果itdetails中的项目标题和详细数据集。我们可以将它们压缩在一起,以获得每个部分的标题和数据。然后,对于details中的每一行,我们将通过使用解析后的数据值压缩项目头来记录详细值。然后,我们将更新由line.date键控的摘要值:

for items,details in zip(p.it,p.details):
    for line in details:
        summary[line.date[0]].update(dict(zip(items,line.data)))

完成了!看看我们积累的关键是什么:

print summary.keys()

给出:

['20.04.2013', '18.04.2013', '17.04.2013', '19.04.2013']

打印“2013年4月18日”的累积数据:

print summary['18.04.2013']

给出:

{1: Decimal('548481.10'), 2: Decimal('46383.00'), 3: Decimal('29810.00'), 4: Decimal('548481.10'), 5: Decimal('56383.00')}

相关问题 更多 >