2016-11-18 2 views
2

Ich habe ein einfaches Beispiel, wo ich 2 Zeilen Daten analysieren möchte.Wie kann ich eine Liste von Werten aus dem Ergebnisobjekt in PyParsing abrufen?

In [1] from pyparsing import Word, nums, OneOrMore, Optional, Suppress, alphanums, LineEnd, LineStart 

     Float = Word(nums + '.' + '-') 
     Name = Word(alphanums) 
     Line = OneOrMore(Float)('data') + Suppress(Optional(';')) + Optional('%') + Optional(Name)('name') 

     Lines = OneOrMore(Line + LineEnd()) 

     string = ''' 1 10 0  T20 
      1 76 0 T76 
     ''' 
     result = Lines.parseString(string) 

In [2] result 
Out[2] (['1', '10', '0', 'T20', '\n', '1', '76', '0', 'T76', '\n'], {'data': [(['1', '10', '0'], {}), (['1', '76', '0'], {})], 'name': ['T20', 'T76']}) 

Das Ergebnis Objekt enthält alle Werte I erforderlich ist, das heißt, die Werte von data und die name Schlüssel werden Listen mit Elementen auf der Linie basierend geordert. Wie bekomme ich die Werte von Ergebnisobjekt?

das Datenattribut Zugriff nicht geben beide Reihen

In [3] result.data 
Out[3] (['1', '76', '0'], {}) 

In [4] for i in result.data: 
      print i 
     1 
     76 
     0 

Die asDict() Methode gibt nur die zweite Reihe

In [5]: result.asDict() 
Out[5]: {'data': ['1', '76', '0'], 'name': 'T76'} 

Die asList() Methode gibt alle Daten in einer einzigen Liste, und es ist schwierig, aufzulisten, wenn Sie nicht wissen, die Länge name und data vor der Zeit

asXML() enthält alles, was ich brauche, aber es ist im XML-Format, und der DocString sagt, es wird bald veraltet sein.

In [7]: print result.asXML() # The documentation says this will be deprecated 
     <data> 
      <data>1</data> 
      <ITEM>10</ITEM> 
      <ITEM>0</ITEM> 
      <name>T20</name> 
      <ITEM> 
     </ITEM> 
      <data>1</data> 
      <ITEM>76</ITEM> 
      <ITEM>0</ITEM> 
      <name>T76</name> 
      <ITEM> 
     </ITEM> 
     </data> 

dump() enthält wiederum teilweise die relevanten Informationen, aber es gibt einen String und man würde die Zeichenfolge wieder für Informationen zu analysieren haben.

In [8]: print result.dump() 
     ['1', '10', '0', 'T20', '\n', '1', '76', '0', 'T76', '\n'] 
     - data: ['1', '76', '0'] 
     - name: 'T76' 

Wie erhält man diese Werte in einer pythonischen Weise?

Antwort

1

Gut gemacht bei der Verwendung von Ergebnisnamen, sie sind unglaublich hilfreich beim Zugriff auf die geparsten Felder. Aber es klingt wie Sie eine Schicht Strukturierung zu Ihrem Parser hinzufügen müssen, so dass jede Zeile ihre eigenen Daten erhält, Name usw. können Sie das tun, indem Sie gerade Linien als neu zu definieren:

Lines = OneOrMore(Group(Line) + LineEnd().suppress()) 

Nun, wenn Sie print (result.dump()) erhalten Sie:

[['1', '10', '0', 'T20'], ['1', '76', '0', 'T76']] 
[0]: 
    ['1', '10', '0', 'T20'] 
    - data: ['1', '10', '0'] 
    - name: 'T20' 
[1]: 
    ['1', '76', '0', 'T76'] 
    - data: ['1', '76', '0'] 
    - name: 'T76' 

Die Ausgabe von dump() ist nicht dazu gedacht, die Werte zu erhalten, analysiert wird, ist gemeint, Ihnen zu helfen, zu zeigen, wie die strukturierten Werte abgerufen werden können. Zum Beispiel können Sie tun:

print(result[1].data) 
print(result[1].name) 

und

['1', '76', '0'] 
T76 

oder erhalten:

for parsed_line in result: 
    print("{name}: {data}".format_map(parsed_line)) 

und erhalten:

T20: ['1', '10', '0'] 
T76: ['1', '76', '0'] 
+1

Wow vielen Dank für die ausführliche und sehr hilfreiche Antwort Paul. Ich mag es wirklich, wie man nicht nur eine gute Antwort auf die gestellte Frage gibt, sondern auch immer wieder ein paar zusätzliche Leckerbissen hineinschleppt (ich wusste bis jetzt noch nicht über format_map) :) Nochmals vielen Dank und großartige Arbeit für das Paket ! – kdheepak

Verwandte Themen