2012-06-19 13 views
5

Ich bin ziemlich neu in Python, und ich versuche, eine Datei zu analysieren. Nur bestimmte Zeilen in der Datei enthalten Daten, die von Interesse sind, und ich möchte mit einem Wörterbuch der Dateien enden, die von gültigen übereinstimmenden Zeilen in der Datei analysiert wurden.Erstellen Sie ein Wörterbuch aus erfolgreichen Regex Übereinstimmungen in Python

Der Code unten funktioniert, aber es ist ein bisschen hässlich und ich versuche zu lernen, wie es getan werden sollte, vielleicht mit einem Verständnis, oder auch mit einem Multiline-Regex. Ich benutze Python 3.2.

file_data = open('x:\\path\\to\\file','r').readlines() 
my_list = [] 
for line in file_data: 
    # discard lines which don't match at all 
    if re.search(pattern, line): 
     # icky, repeating search!! 
     one_tuple = re.search(pattern, line).group(3,2) 
     my_list.append(one_tuple) 
my_dict = dict(my_list) 

Können Sie eine bessere Implementierung vorschlagen?

+2

Verständnis kann schön sein, aber Sie können eine Variable nicht einfach an einen Wert in ihnen binden, also würden Sie das doppelte 're.search' brauchen. Benutze einfach eine Schleife. –

Antwort

4

Vielen Dank für die Antworten. Nachdem ich sie zusammengesetzt habe, habe ich

file_data = open('x:\\path\\to\\file','r').read() 
my_list = re.findall(pattern, file_data, re.MULTILINE) 
my_dict = {c:b for a,b,c in my_list} 

aber ich glaube nicht, dass ich heute ohne die Hilfe dorthin gekommen wäre.

+2

Vielleicht möchten Sie die erste Gruppe in Ihrem Regex nicht erfassen ('?:'), Um den Verständnisschritt zu überspringen: 'my_dict = dict (re.findall ...)' – georg

+0

Ziemlich gute Verbesserung. Jedoch: das Lesen aller Daten in eine Variable, anstatt über ein Dateiobjekt zu iterieren (und implizit die 'readline()' Methode), ist nicht sehr skalierbar. 're.findall()' funktioniert perfekt auf einem Iterator und nicht auf einer Variablen. – smci

4

Hier einige quick'n'dirty Optimierungen an Ihrem Code:

my_dict = dict() 

with open(r'x:\path\to\file', 'r') as data: 
    for line in data: 
     match = re.search(pattern, line) 
     if match: 
      one_tuple = match.group(3, 2) 
      my_dict[one_tuple[0]] = one_tuple[1] 
+0

Danke, das hat geholfen – WiringHarness

1

Ich bin nicht sicher, ich würde empfehlen, aber hier ist eine Art und Weise Sie stattdessen ein Verständnis könnten versuchen, zu verwenden (I substituierte String für die Datei der Einfachheit halber)

>>> import re 
>>> data = """1foo bar 
... 2bing baz 
... 3spam eggs 
... nomatch 
... """ 
>>> pattern = r"(.)(\w+)\s(\w+)" 
>>> {x[0]: x[1] for x in (m.group(3, 2) for m in (re.search(pattern, line) for line in data.splitlines()) if m)} 
{'baz': 'bing', 'eggs': 'spam', 'bar': 'foo'} 
+0

Dict Verständnis; Ich mag das! – WiringHarness

2

im Geiste der EAFP würde ich vorschlagen,

with open(r'x:\path\to\file', 'r') as data: 
    for line in data: 
     try: 
      m = re.search(pattern, line) 
      my_dict[m.group(2)] = m.group(3) 
     except AttributeError: 
      pass 

Eine andere Möglichkeit besteht darin, weiterhin Listen zu verwenden, aber das Muster so zu ändern, dass es nur zwei Gruppen enthält: (key, value). Dann könnten Sie einfach tun:

matches = [re.findall(pattern, line) for line in data] 
    mydict = dict(x[0] for x in matches if x) 
+0

Finden ist hilfreich. – WiringHarness

1
matchRes = pattern.match(line) 
if matchRes: 
    my_dict = matchRes.groupdict() 
+0

Bitte folgen Sie Ihrem Code-Schnipsel mit einigen Details, Erklärungen, um für Leser klarer zu sein. –

Verwandte Themen