【问题标题】:String to Dictionary in PythonPython中的字符串到字典
【发布时间】:2011-06-22 11:12:18
【问题描述】:

所以我在这方面花了很多时间,在我看来这应该是一个简单的解决方法。我正在尝试使用 Facebook 的身份验证在我的网站上注册用户,并且正在尝试在服务器端进行。我已经到了获得访问令牌的地步,当我去的时候:

https://graph.facebook.com/me?access_token=MY_ACCESS_TOKEN

我得到的信息是这样的字符串:

{"id":"123456789","name":"John Doe","first_name":"John","last_name":"Doe","link":"http:\/\/www.facebook.com\/jdoe","gender":"male","email":"jdoe\u0040gmail.com","timezone":-7,"locale":"en_US","verified":true,"updated_time":"2011-01-12T02:43:35+0000"}

看来我应该只能在此使用dict(string),但我收到了这个错误:

ValueError: dictionary update sequence element #0 has length 1; 2 is required

所以我尝试使用 Pickle,但收到此错误:

KeyError: '{'

我尝试使用django.serializers 对其进行反序列化,但结果相似。有什么想法吗?我觉得答案必须很简单,而我只是愚蠢。感谢您的帮助!

【问题讨论】:

  • 如果您想将字符串作为 Python 进行评估,您可能需要更改您的字符串:"verified":true 失败,除非定义了 true。或者你可以使用"verified":True,或"verified":"true"
  • @Matt:我怀疑他可以改变 graph.facebook.com 的输出格式。
  • @Fred:鉴于问题的标题(“Python 中的字符串到字典”),我猜他可以在调用ast.literal_eval() 之前将其从 Python 更改。不过,您的(修改后的)答案是正确的 - JSON 反序列化器是更好的解决方案。
  • @MattCurtis:以稳健的方式(在 ast.literal_eval 之前)更改它首先需要将其解析为 JSON。我提到 ast.literal_eval 是执行 OP 尝试对 dict(some_string) 执行的操作的正确方法。
  • @Fred:我想我们同意了 :-)

标签: python string json facebook dictionary


【解决方案1】:

这个数据是JSON!如果您使用的是 Python 2.6+,则可以使用内置的 json module 对其进行反序列化,否则您可以使用优秀的第三方 simplejson module

import json    # or `import simplejson as json` if on Python < 2.6

json_string = u'{ "id":"123456789", ... }'
obj = json.loads(json_string)    # obj now contains a dict of the data

【讨论】:

  • 你为什么把u放在你的示例JSON字符串前面?
  • @John:表示Unicode string。我说它主要是出于习惯,但大概 Facebook API 可以返回包含非 ASCII 字符的数据;在这种情况下,数据将被编码(可能是 UTF-8),decode()-ing 它会产生一个unicode 字符串——这就是我在示例中使用的。此外,this page 提到 JSON 始终采用 Unicode(搜索该术语,大约是一半)
  • 它表示 Python 中的小 u unicode 文字。习惯不是一个好的理由。 “JSON 文本的字符编码始终是 Unicode。” -- [Uu]nicode 不是编码。 json.loads() 期望的是你“通过网络”得到的东西,它通常是一个用 ASCII 编码的 str 对象。唯一会故意为 json.loads() 提供 unicode 对象的情况是某个陌生人以 UTF-16 传输它,并且据记录,您需要自己对其进行解码。
  • @John:是的,small-u unicode 是 Python 类型,它包含一个 Unicode(big-U 专有名词)字符串。我也同意 Unicode 根本不是一种编码,所以也许我不应该指向那个页面作为参考。没有理由避免将 unicode 字符串传递给 json.loads,尽管 - docs 明确表示这是完全可以接受的,我喜欢使用预解码的字符串,因为它更明确。
  • @John: 很抱歉是迂腐的,但是json.loads() 不希望有一个用 ASCII 编码的 str 对象——它需要一个用 UTF-8str 对象/i> 或 unicode 对象(或 str 对象加上显式编码)
【解决方案2】:

使用 ast.literal_eval 评估 Python 文字。但是,您所拥有的是 JSON(例如注意“true”),因此请使用 JSON 反序列化器。

>>> import json
>>> s = """{"id":"123456789","name":"John Doe","first_name":"John","last_name":"Doe","link":"http:\/\/www.facebook.com\/jdoe","gender":"male","email":"jdoe\u0040gmail.com","timezone":-7,"locale":"en_US","verified":true,"updated_time":"2011-01-12T02:43:35+0000"}"""
>>> json.loads(s)
{u'first_name': u'John', u'last_name': u'Doe', u'verified': True, u'name': u'John Doe', u'locale': u'en_US', u'gender': u'male', u'email': u'jdoe@gmail.com', u'link': u'http://www.facebook.com/jdoe', u'timezone': -7, u'updated_time': u'2011-01-12T02:43:35+0000', u'id': u'123456789'}

【讨论】:

    【解决方案3】:

    在 Python 3.x 中

    import json
    t_string = '{"Prajot" : 1, "Kuvalekar" : 3}'
    res = json.loads(t_string)
    print(res) # <dict>  {"Prajot" : 1, "Kuvalekar" : 3}
    

    【讨论】:

      猜你喜欢
      • 2012-10-11
      • 2019-09-26
      • 2012-08-11
      • 2013-11-05
      • 2021-12-11
      • 2011-01-18
      • 1970-01-01
      • 2021-11-23
      • 2015-02-01
      相关资源
      最近更新 更多