2013-05-15 27 views
0

我在以下格式的字符串:字符串處理而解析成字典

"2A:xxx\r\n3A:yyyy\r\n51:yzzzz\r\n52:yzyeys\r\n4A:....." 

這需要通過分裂在\ r \ n轉換成一個字典。
然而,困難的部分是這樣的事實:對於3A和4A之間的配對,密鑰需要由3A預先填寫,以使其明顯是3A的子集。
所以最終的預期輸出如下:

{'2A':'xxxx','3A':'yyyy','3A-51':'yzzzz','3A-52':'yzyeys','4A':'.....} 

難道還有比將所有數據提取到一個字典,並通過字典用迭代後for循環的任何簡單的方法。 這可以在一個單一的解析過程中完成嗎?

回答

1

關閉我的頭頂:

dct = {} 
last = '' 
for line in s.splitlines(): 
    key, val = line.split(':') 
    if key.isdigit(): 
     key = last + '-' + key 
    else: 
     last = key 
    dct[key] = val 

這工作,但有「複合」鍵一般不具有層次結構的工作的最佳途徑。我建議這樣的事情,而不是:

dct = {} 
last = '' 
for line in s.splitlines(): 
    key, val = line.split(':') 
    if key.isdigit(): 
     dct[last].setdefault('items', {})[key] = {'value': val } 
    else: 
     dct[key] = {'value': val } 
     last = key 

這使得像一個字典:

{'2A': {'value': 'xxx'}, 
'3A': {'items': {'51': {'value': 'yzzzz'}, '52': {'value': 'yzyeys'}}, 
     'value': 'yyyy'}, 
'4A': {'value': '.....'}} 

看起來比較複雜,但實際上這將是更容易的工作。

1

str.splitlines()完成大部分工作的你:

>>> "2A:xxx\r\n3A:yyyy\r\n51:yzzzz\r\n52:yzyeys\r\n4A:.....".splitlines() 
['2A:xxx', '3A:yyyy', '51:yzzzz', '52:yzyeys', '4A:.....'] 

棘手位這裏跟蹤3A鍵;據推測,這是定義層次結構的關鍵字中的A

這是最好的拆分出去發電機:

def hierarchy_key_values(lines): 
    parent = '' 
    for line in lines: 
     key, value = line.split(':', 1) 
     if key[-1] == 'A': 
      parent = key + '-' 
     else: 
      key = parent + key 

     yield key, value 

其餘很簡單:

your_dict = dict(hierarchy_key_values(input_text.splitlines())) 

演示你的榜樣輸入:

>>> dict(hierarchy_key_values(input_text.splitlines())) 
{'3A-52': 'yzyeys', '3A': 'yyyy', '3A-51': 'yzzzz', '2A': 'xxx', '4A': '.....'} 
0

隨着reduce功能你可以在迭代的同時保持記憶,然後用單線形成功:

>>> import re 
>>> reduce(lambda col, x: x + [y if re.match(r'\d+A.*', y) else col[-1][0:2] + '-' + y], s.split('\r\n'), []) 
['2A:xxx', '3A:yyyy', '3A-51:yzzzz', '3A-52:yzyeys', '4A:.....'] 

正如馬丁所說,split函數把字符串轉換部分,reduce收集被填充的收集和新元素。因此,您可以查看添加的最後一個元素(x[-1])以獲取其標識符。

0
def solve(strs): 
    dic = {} 
    prev = None 
    for x in strs.splitlines(): 
     key,val = x.split(":") 
     if "A" not in key:    #or key.isdigit() 
      new_key = "-".join((prev,key)) 
      dic[new_key] = val 
     else: 
      dic[key] = val 
      prev = key 
    return dic 
strs = "2A:xxx\r\n3A:yyyy\r\n51:yzzzz\r\n52:yzyeys\r\n4A:" 
print solve(strs)  

輸出:

{'3A-52': 'yzyeys', '3A': 'yyyy', '3A-51': 'yzzzz', '2A': 'xxx', '4A': ''}