2015-10-07 7 views
5

मेरे पास एक फ़ाइल है जिसमें इस प्रकार के प्रारूप में रेखाएं हैं।कुंजी मान जोड़े के एकाधिक परतों के साथ एक शब्दकोश में एक पंक्ति को विभाजित करें

Example 1: 
nextline = "DD:MM:YYYY INFO - 'WeeklyMedal: Hole = 1; Par = 4; Index = 2; Distance = 459; Score = { Player1 = 4 };" 

Example 2: 
nextline = "DD:MM:YYYY INFO - 'WeeklyMedal: Hole = 1; Par = 4; Index = 2; Distance = 459; Score = { Player1 = 4; Player2 = 6; Player3 = 4 };" 

मैंने पहली बार ':' द्वारा लाइन को विभाजित किया जो मुझे 2 प्रविष्टियों के साथ एक सूची देता है। मैं इस लाइन को एक कुंजी और मान के साथ एक शब्दकोश में विभाजित करना चाहता हूं, लेकिन जहां स्कोर कुंजी में मान के साथ कई उप-कुंजी हैं।

Hole 1 
Par 4 
Index 2 
Distance 459 
Score 
    Player1 4 
    Player2 6 
    Player3 4 

तो मैं कुछ इस तरह उपयोग कर रहा हूँ ...

split_line_by_semicolon = nextline.split(":") 
dictionary_of_line = dict((k.strip(), v.strip()) for k,v in (item.split('=')  
    for item in split_line_by_semicolon.split(';'))) 
     for keys,values in dictionary_of_line.items(): 
      print("{0} {1}".format(keys,values)) 

हालांकि मैं रेखा के score तत्व पर कोई त्रुटि मिलती है:

ValueError: too many values to unpack (expected 2) 

मैं विभाजन पर समायोजित कर सकते हैं '=' से, इसलिए यह पहले '='

dictionary_of_line = dict((k.strip(), v.strip()) for k,v in (item.split('=',1)  
    for item in split_line_by_semicolon.split(';'))) 
     for keys,values in dictionary_of_line.items(): 
      print("{0} {1}".format(keys,values)) 
के बाद बंद हो जाता है

हालांकि मैं घुंघराले ब्रैकेट के भीतर उप मान खो देता हूं। क्या कोई जानता है कि मैं इस बहु परत शब्दकोश को कैसे प्राप्त कर सकता हूं?

+0

'split_line_by_semicolon.split (',')' मेरे लिए सही नहीं लगता है। 'split_line_by_semicolon' एक सूची है, और सूचियों में 'स्प्लिट' विधि नहीं है। क्या आप वाकई कोड चला रहे हैं? – Kevin

+0

सही। उस रेखा में कुछ अन्य चीजें हैं जो मैं इसके मांस तक पहुंचने के लिए बाहर निकलती हूं। तो यह वास्तव में split_line_by_semicolon [3] – John

उत्तर

2

एक आसान तरीका यह करने के लिए (लेकिन अगर यह अपनी स्थिति में स्वीकार्य है मैं नहीं जानता) होगा:

import re 

nextline = "DD:MM:YYYY INFO - 'WeeklyMedal: Hole = 1; Par = 4; Index = 2; Distance = 459; Score = { Player1 = 4; Player2 = 6; Player3 = 4 };" 

# compiles the regular expression to get the info you want 
my_regex = re.compile(r'\w+ \= \w+') 

# builds the structure of the dict you expect to get 
final_dict = {'Hole':0, 'Par':0, 'Index':0, 'Distance':0, 'Score':{}} 

# uses the compiled regular expression to filter out the info you want from the string 
filtered_items = my_regex.findall(nextline) 

for item in filtered_items: 
    # for each filtered item (string in the form key = value) 
    # splits out the 'key' and handles it to fill your final dictionary 
    key = item.split(' = ')[0] 
    if key.startswith('Player'): 
     final_dict['Score'][key] = int(item.split(' = ')[1]) 
    else: 
     final_dict[key] = int(item.split(' = ')[1]) 
+1

धन्यवाद। मुझे यह पसंद है। पूरी तरह से फिट बैठता है। – John

0
lines = "DD:MM:YYYY INFO - 'WeeklyMedal: Hole = 1; Par = 4; Index = 2; Distance = 459; Score = { Player1 = 4 };", "DD:MM:YYYY INFO - 'WeeklyMedal: Hole = 1; Par = 4; Index = 2; Distance = 459; Score = { Player1 = 4; Player2 = 6; Player3 = 4 };" 

def lines_to_dict(nextline): 
    import json 
    # cut up to Hole 
    nextline = nextline[nextline.index("Hole"):] 
    # convert to dict format 
    string_ = re.sub(r'\s+=',':',nextline) 
    string_ = re.sub(r';',',',string_) 
    # json likes double quotes 
    string_ = re.sub(r'(\b\w+)',r'"\1"',string_) 
    string_ = re.sub(r',$',r'',string_) 
    # make dict for Hole 
    mo = re.search(r'(\"Hole.+?),\W+Score.*',string_) 
    if mo: 
     d_hole = json.loads("{" + mo.groups()[0] + "}") 
    # make dict for Score 
    mo = re.search(r'(\"Score.*)',string_) 
    if mo: 
     d_score = json.loads("{" + mo.groups()[0] + "}") 
    # combine dicts 
    d_hole.update(d_score) 
    return d_hole 

for d in lines: 
pprint.pprint(lines_to_dict(d)) 

{'Distance': '459', 
'Hole': '1', 
'Index': '2', 
'Par': '4', 
'Score': {'Player1': '4'}} 

{'Distance': '459', 
'Hole': '1', 
'Index': '2', 
'Par': '4', 
'Score': {'Player1': '4', 'Player2': '6', 'Player3': '4'}} 
1

मैं के रूप में maccinza किया एक ही तरीके से नियमित अभिव्यक्ति का प्रयोग करेंगे (मैं उसका जवाब की तरह), एक मामूली अंतर के साथ - भीतरी शब्दकोश के साथ एक डेटा में यह रिकर्सिवली संसाधित किया जा सकता:

#example strings: 
nextline1 = "DD:MM:YYYY INFO - 'WeeklyMedal: Hole = 1; Par = 4; Index = 2; Distance = 459; Score = { Player1 = 4 };" 
nextline2 = "DD:MM:YYYY INFO - 'WeeklyMedal: Hole = 1; Par = 4; Index = 2; Distance = 459; Score = { Player1 = 4; Player2 = 6; Player3 = 4 };" 

import re 
lineRegexp = re.compile(r'.+\'WeeklyMedal:(.+)\'?') #this regexp returns WeeklyMedal record. 
weeklyMedalRegexp = re.compile(r'(\w+) = (\{.+\}|\w+)') #this regexp parses WeeklyMedal 

#helper recursive function to process WeeklyMedal record. returns dictionary 
parseWeeklyMedal = lambda r, info: { k: (int(v) if v.isdigit() else parseWeeklyMedal(r, v)) for (k, v) in r.findall(info)} 
parsedLines = [] 
for line in [nextline1, nextline2]: 
    info = lineRegexp.search(line) 
    if info: 
     #process WeeklyMedal record 
     parsedLines.append(parseWeeklyMedal(weeklyMedalRegexp, info.group(0))) 
     #or do something with parsed dictionary in place 

# do something here with entire result, print for example 
print(parsedLines) 
संबंधित मुद्दे