【问题标题】:Python string.split doesn't do what I was expectingPython string.split 没有达到我的预期
【发布时间】:2013-05-25 21:53:42
【问题描述】:

我有一个字符串,里面有一堆奇怪的东西,我想把它分解成一个列表:

"44":{"1":4.6,"0":1.53,"2":7.2},"53":{"1":4.2,"0":1.4,"2":6.75},"121":{"1":3.2,"0":1.6,"2":6}

理想情况下,我希望:

"44":{"1":4.6,"0":1.53,"2":7.2}
"53":{"1":4.2,"0":1.4,"2":6.75}
"121":{"1":3.2,"0":1.6,"2":6}

但我会满足于在每个 } 处拆分。

mystring.split('}') 似乎出于某种原因将我的字符串拆分为每个字符一个元素的列表。不知道我做错了什么。救命!

【问题讨论】:

  • String.split('}') 在此字符串上为您提供['"44":{"1":4.6,"0":1.53,"2":7.2', ',"53":{"1":4.2,"0":1.4,"2":6.75', ',"121":{"1":3.2,"0":1.6,"2":6', ''] - 这与您的预期有何不同?
  • 那个字符串是什么?这个从哪里来?你打算用它做什么? “一堆怪事”有点含糊……
  • 您的输入几乎是 JSON;这是一个字典的内容,只是缺少括号。

标签: python json deserialization


【解决方案1】:

几乎看起来像有效的 JSON。

>>> s = '"44":{"1":4.6,"0":1.53,"2":7.2},"53":{"1":4.2,"0":1.4,"2":6.75},"121":{"1":3.2,"0":1.6,"2":6}'
>>> import json
>>> d = json.loads("{" + s + "}")
>>> d
{'53': {'2': 6.75, '0': 1.4, '1': 4.2}, '44': {'2': 7.2, '0': 1.53, '1': 4.6}, '
121': {'2': 6, '0': 1.6, '1': 3.2}}
>>> for key,value in d.items():
...    print("Key: {0} - Value: {1}".format(key,value))
...
Key: 53 - Value: {'2': 6.75, '0': 1.4, '1': 4.2}
Key: 44 - Value: {'2': 7.2, '0': 1.53, '1': 4.6}
Key: 121 - Value: {'2': 6, '0': 1.6, '1': 3.2}

【讨论】:

  • 或者,要获得 OP 想要的格式(字符串列表):result = ['{}:{}'.format(json.dumps(key), json.dumps(value)) for key, value in d.items()]
【解决方案2】:

你可以试试这个:

s = '"44":{"1":4.6,"0":1.53,"2":7.2},"53":{"1":4.2,"0":1.4,"2":6.75},"121":{"1":3.2,"0":1.6,"2":6}'
h = eval("{"+s+"}")
for k in h: print k,h[k]

但由于 eval 不安全,因为它可以执行任意代码,所以最好使用 literal_eval。 literal_eval 仅适用于有效数据类型:

from ast import literal_eval
s = # ....
h = literal_eval("{"+s+"}")
for k in h: print k,h[k]

输出

121 {'1': 3.2, '0': 1.6, '2': 6}
44 {'1': 4.6, '0': 1.53, '2': 7.2}
53 {'1': 4.2, '0': 1.4, '2': 6.75}

【讨论】:

  • 当有更好的替代品(如ast.literal_eval()或JSON)时,请不要鼓励人们使用eval()
【解决方案3】:

你可以这样做:

>>> string = '"44":{"1":4.6,"0":1.53,"2":7.2},"53":{"1":4.2,"0":1.4,"2":6.75},"121":{"1":3.2,"0":1.6,"2":6}'
>>> string.replace('},','}***').split('***')
['"44":{"1":4.6,"0":1.53,"2":7.2}', '"53":{"1":4.2,"0":1.4,"2":6.75}', '"121":      {"1":3.2,"0":1.6,"2":6}']

【讨论】:

    【解决方案4】:

    您的问题的正确答案取决于允许使用哪种表达方式。如果表达式可能包含嵌套大括号,那么您需要递归正则表达式。以下解决方案不支持嵌套大括号,但足以解析您的示例:

        for token in re.findall(r'((?:[^{,]|{.*?})+)', mystring):
            print token
    

    【讨论】:

      【解决方案5】:

      您的输入几乎是 JSON;这是一个字典的内容,只是缺少括号

      import json
      nearly_json = '"44":{"1":4.6,"0":1.53,"2":7.2},"53":{"1":4.2,"0":1.4,"2":6.75},"121":{"1":3.2,"0":1.6,"2":6}'
      
      d = json.loads(f'{{ {nearly_json} }}') # Add the missing enclosing braces, and convert to Python (deserialize)...
      
      d
      {'44': {'1': 4.6, '0': 1.53, '2': 7.2}, '53': {'1': 4.2, '0': 1.4, '2': 6.75}, '121': {'1': 3.2, '0': 1.6, '2': 6}}
      
      d['44']
      {'1': 4.6, '0': 1.53, '2': 7.2}
      

      正如 TimPietzcker 所说,您现在可以遍历 dict,例如与.items() 或者你可以访问它的.keys()

      【讨论】:

        【解决方案6】:

        只用逗号分开?

        print '"44":{"1":4.6,"0":1.53,"2":7.2},"53":{"1":4.2,"0":1.4,"2":6.75},"121":{"1":3.2,"0":1.6,"2":6}'.split(',')
        

        给予:

        ['"44":{"1":4.6', '"0":1.53', '"2":7.2}', '"53":{"1":4.2', '"0":1.4', '"2":6.75}', '"121":{"1":3.2', '"0":1.6', '"2":6}']
        

        这是你要求的。

        【讨论】:

        • 这根本不是 OP 所要求的。他希望第一个字符串是"44":{"1":4.6,"0":1.53,"2":7.2},而你给了他"44":{"1":4.6
        猜你喜欢
        • 2021-10-15
        • 2016-09-05
        • 1970-01-01
        • 2012-05-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-03-27
        • 1970-01-01
        相关资源
        最近更新 更多