将带有换行符和制表符的python字符串转换为字典

时间:2015-11-04 17:48:20

标签: python string dictionary split

我对这个我遇到的特殊问题有点困惑。我有一个有效的解决方案,但我认为它不是Pythonic。

我有一个原始文本输出:

Key 1   
  Value 1 
Key 2   
  Value 2 
Key 3   
  Value 3a  
  Value 3b
  Value 3c 
Key 4   
  Value 4a  
  Value 4b

我正在尝试制作字典:

{ 'Key 1': ['Value 1'], 'Key 2': ['Value 2'], 'Key 3': ['Value 3a', 'Value 3b', 'Value 3c'], 'Key 4': ['Value 4a', 'Value 4b'] }

原始输出可以变成一个字符串,它看起来像这样:

my_str = "
Key 1\n\tValue 1
\nKey 2\n\tValue 2
\nKey 3\n\tValue 3a \n\tValue 3b \n\tValue 3c
\nKey 4\n\tValue 4a \n\tValue 4b "

因此值由\ n \ t分隔,并且键由\ n

分隔

如果我尝试做这样的事情:

dict(item.split('\n\t') for item in my_str.split('\n'))

它没有正确解析它,因为它会分割' n'在\ n \ t中也是如此。

到目前为止,我有这样的事情:

#!/usr/bin/env python

str = "Key 1\n\tValue 1\nKey 2\n\tValue 2\nKey 3\n\tValue 3a \n\tValue 3b \n\tValue 3c\nKey 4\n\tValue 4a \n\tValue 4b"

output = str.replace('\n\t', ',').replace('\n',';')
result = {}
for key in output.split(';'):
  result[key.split(',')[0]] = key.split(',')[1:]
print result

返回:

{'Key 1': ['Value 1'], 'Key 2': ['Value 2'], 'Key 3': ['Value 3a ', 'Value 3b ', 'Value 3c'], 'Key 4': ['Value 4a ', 'Value 4b']}

然而,这对我来说非常严重,我只是想知道是否有一种pythonic方式来做到这一点。任何帮助都会非常感激!

4 个答案:

答案 0 :(得分:4)

包含电池 - defaultdict处理自动保存新密钥的值作为列表,我们利用str的{​​{1}}方法检查缩进(否则我们可以使用正则表达式):

iswhitespace

答案 1 :(得分:1)

itertools.groupby在这里很有用。您可以通过缩进对相邻行进行分组,然后使用extend一次性将相邻的缩进行插入到词典中:

my_str = """Key 1\n\tValue 1\nKey 2\n\tValue 2\nKey 3\n\tValue 3a \n\tValue 3b \n\tValue 3c\nKey 4\n\tValue 4a \n\tValue 4b"""

def get_indent(line):
    return len(line) - len(line.lstrip())

res = {}
for indent, tokens in itertools.groupby(my_str.splitlines(), lambda line: get_indent):
    if indent == 0:
        cur_key = list(tokens)[0]
        res[cur_key] = []
    else:
        res[cur_key].extend( token.strip() for token in tokens )

print(res)
{'Key 3': ['Value 3a', 'Value 3b', 'Value 3c'],
 'Key 4': ['Value 4a', 'Value 4b'],
 'Key 2': ['Value 2'],
 'Key 1': ['Value 1']}

答案 2 :(得分:0)

我发现每当一个人开始将一堆操作链接在一起时(就像在你的“result.setdefault ...”行中一样),你就会弄清楚可能非常简单的问题。

str = "Key 1\n\tValue 1\nKey 2\n\tValue 2\nKey 3\n\tValue 3a \n\tValue 3b \n\tValue 3c\nKey 4\n\tValue 4a \n\tValue 4b"

output = str.replace('\n\t', ',').replace('\n',';')
result = {}
for group in output.split(';'):
    values = group.split(',')
    key = values[0]
    result[key] = []
    for v in values[1:]:
        result[key].append(v)
print result

收率:

{'Key 1': ['Value 1'], 'Key 2': ['Value 2'], 'Key 3': ['Value 3a ', 'Value 3b ', 'Value 3c'], 'Key 4': ['Value 4a ', 'Value 4b']}

答案 3 :(得分:0)

显然你无法从原始文本输出中删除\ n和\ t \ t \ t \ t \ t \ t \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n \ n>

b''

将会是这样的

Key 1     
  Value 1   
Key 2     
  Value 2 
Key 3  
  Value 3a  
  Value 3b

然后你可以用以下方式使用json解析器

"Key 1":[      
  Value 1   
],   
"Key 2":[     
  Value 2  
],  
"Key 3":[
  Value 3a,  
  Value 3b
]