【问题标题】:how to parse a string into a dictionary如何将字符串解析成字典
【发布时间】:2015-02-02 01:16:12
【问题描述】:

我正在尝试解析字符串以分隔字符串中的列表。我目前有字符串:

string = "[['q1', '0', 'q1'], ['q1', '1', 'q2'], ['q2', '0', 'q2'], ['q2', '1', 'q1']]"

有没有办法解析字符串,使字典键是列表的第一个元素,键的值是元素的下一个元素。例如:

{'q1': ('0','q1'), 'q1': ('1','q2'), 'q2': ('0','q2'), 'q2': ('1', 'q1')}

【问题讨论】:

  • 您不能将字典中的重复元素作为键。 q1 和 q2 在您的预期输出中重复两次,您不能这样做。
  • 除非你通过重新定义一个类来改变 Python 字典的行为,但我想这不是目的 :)
  • 有没有办法向字典中的现有键添加另一个值?
  • 是的,你可以喜欢:{'q1': [('0','q1'), ('1','q2')], 'q2': [('0','q2'), ('1', 'q1')]}。这是你想要的吗?

标签: python dictionary


【解决方案1】:

dictionary 的 Insted 您可以拥有列表:
你可以使用ast.literal_eval从字符串中解析python数据结构

>>> import ast
>>> my_string = "[['q1', '0', 'q1'], ['q1', '1', 'q2'], ['q2', '0', 'q2'], ['q2', '1', 'q1']]"
>>> k = ast.literal_eval(my_string)
>>> k
[['q1', '0', 'q1'], ['q1', '1', 'q2'], ['q2', '0', 'q2'], ['q2', '1', 'q1']]
>>> [[x[0],tuple(x[1:])] for x in k]
[['q1', ('0', 'q1')], ['q1', ('1', 'q2')], ['q2', ('0', 'q2')], ['q2', ('1', 'q1')]]

【讨论】:

  • 这行得通,我的问题已得到解决。谢谢!
【解决方案2】:

您可以使用 JSON,但 字符串格式必须是 dict,并且您不能有 2 次相同的键

import json

string ='{"q": ["0", "q1"], "q1": ["1", "q2"], "q3": ["1", "q1"], "q2": ["0", "q2"]}'

dict = json.loads(string)

print dict
Output: {'q': ['0', 'q1'], 'q1': ['1', 'q2'], 'q3': ['1', 'q1'], 'q2': ['0', 'q2']}

【讨论】:

  • 列表列表是有效的 JSON,问题是 OP 的字符串包含单引号而不是双引号。
【解决方案3】:

保留重复并符合输入格式:

import collections
import json
string = "[['q1', '0', 'q1'], ['q1', '1', 'q2'], ['q2', '0', 'q2'], ['q2', '1', 'q1']]"
d = collections.defaultdict(list)
for (k, v1, v2) in json.loads(string.replace("'",'"')):
    d[k].append((v1, v2))

使用eval(如果您相信您的输入):

import collections
string = "[['q1', '0', 'q1'], ['q1', '1', 'q2'], ['q2', '0', 'q2'], ['q2', '1', 'q1']]"
d = collections.defaultdict(list)
for (k, v1, v2) in eval(string):
    d[k].append((v1, v2))

d的内容:

defaultdict(<type 'list'>, {
    'q1': [('0', 'q1'), ('1', 'q2')],
    'q2': [('0', 'q2'), ('1', 'q1')]
})

编辑:根本没有图书馆。

string = "[['q1', '0', 'q1'], ['q1', '1', 'q2'], ['q2', '0', 'q2'], ['q2', '1', 'q1']]"
d = {}
for (k, v1, v2) in eval(string):
    d.setdefault(k, []).append((v1, v2))

虽然我无法使它成为单线 :-)

【讨论】:

    【解决方案4】:

    您可以从您的字符串中获取嵌套字典(比之前的答案更简单)。感谢 Alex Martelli 回复Update value of a nested dictionary of varying depth

    import ast
    
    def update(d, u):
        for k, v in u.iteritems():
            if isinstance(v, dict):
                r = update(d.get(k, {}), v)
                d[k] = r
            else:
                d[k] = u[k]
        return d
    
    def listToDict(l):
        temp = l[-1]
        for value in l[-2::-1]:
            temp = {value: temp}
        return temp
    
    input = "[['q1', '0', 'q1'], ['q1', '1', 'q2'], ['q2', '0', 'q2'], ['q2', '1', 'q1']]"
    
    res = {}
    for l in ast.literal_eval(input):
        update(res ,listToDict(l))
    print res
    

    输出:

    {'q1': {'1': 'q2', '0': 'q1'}, 'q2': {'1': 'q1', '0': 'q2'}}
    

    【讨论】:

      【解决方案5】:

      试试这个

      >>> import ast
      >>> ast.literal_eval(string)
      [['q1', '0', 'q1'], ['q1', '1', 'q2'], ['q2', '0', 'q2'], ['q2', '1', 'q1']]
      >>> list=ast.literal_eval(string)
      >>> d={}
      >>> for l in list:
      ...     d[l[0]]=tuple(l[1:])
      >>> d
      {'q1': ('1', 'q2'), 'q2': ('1', 'q1')}
      

      key 在 dict 中总是唯一的,这就是结果显示更新的键值对的原因

      【讨论】:

      • 这不是 OP 要求的
      • @Hackaholic 是的,我知道只是给出想法
      • 我没有投反对票。但正如我所说,OP 不想要这个
      猜你喜欢
      • 1970-01-01
      • 2015-06-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多