【问题标题】:SimpleJson handling of same named entitiesSimpleJson 处理相同命名的实体
【发布时间】:2011-10-19 17:13:57
【问题描述】:

我在应用引擎中使用 Alchemy API,所以我使用 simplejson 库来解析响应。问题是响应中的条目具有 sme 名称

 {
    "status": "OK",
    "usage": "By accessing AlchemyAPI or using information generated by AlchemyAPI, you are agreeing to be bound by the AlchemyAPI Terms of Use: http://www.alchemyapi.com/company/terms.html",
    "url": "",
    "language": "english",
    "entities": [
        {
            "type": "Person",
            "relevance": "0.33",
            "count": "1",
            "text": "Michael Jordan",
            "disambiguated": {
                "name": "Michael Jordan",
                "subType": "Athlete",
                "subType": "AwardWinner",
                "subType": "BasketballPlayer",
                "subType": "HallOfFameInductee",
                "subType": "OlympicAthlete",
                "subType": "SportsLeagueAwardWinner",
                "subType": "FilmActor",
                "subType": "TVActor",
                "dbpedia": "http://dbpedia.org/resource/Michael_Jordan",
                "freebase": "http://rdf.freebase.com/ns/guid.9202a8c04000641f8000000000029161",
                "umbel": "http://umbel.org/umbel/ne/wikipedia/Michael_Jordan",
                "opencyc": "http://sw.opencyc.org/concept/Mx4rvViVq5wpEbGdrcN5Y29ycA",
                "yago": "http://mpii.de/yago/resource/Michael_Jordan"
            }
        }
    ]
}

所以问题是“subType”重复了,所以负载返回的字典只是“TVActor”而不是列表。有没有办法解决这个问题?

【问题讨论】:

    标签: python json simplejson


    【解决方案1】:

    定义application/jsonrfc 4627 说:

    An object is an unordered collection of zero or more name/value pairs
    

    还有:

    The names within an object SHOULD be unique.
    

    这意味着 AlchemyAPI 不应在同一对象内返回多个 "subType" 名称并声称它是 JSON。

    您可以尝试以 XML 格式 (outputMode=xml) 请求相同的内容,以避免结果中的歧义或将重复的键值转换为列表:

    import simplejson as json
    from collections import defaultdict
    
    def multidict(ordered_pairs):
        """Convert duplicate keys values to lists."""
        # read all values into lists
        d = defaultdict(list)
        for k, v in ordered_pairs:
            d[k].append(v)
    
        # unpack lists that have only 1 item
        for k, v in d.items():
            if len(v) == 1:
                d[k] = v[0]
        return dict(d)
    
    print json.JSONDecoder(object_pairs_hook=multidict).decode(text)
    

    示例

    text = """{
      "type": "Person",
      "subType": "Athlete",
      "subType": "AwardWinner"
    }"""
    

    输出

    {u'subType': [u'Athlete', u'AwardWinner'], u'type': u'Person'}
    

    【讨论】:

      【解决方案2】:

      The rfc 4627 for application/json media type 建议使用唯一键,但并未明确禁止:

      对象中的名称应该是唯一的。

      来自rfc 2119

      应该这个词,或形容词“推荐”,意味着那里
      在特定情况下可能存在忽略a的正当理由
      特定项目,但必须了解全部含义并
      在选择不同的课程之前仔细权衡。

      这是一个已知问题。

      您可以通过修改重复键来解决这个问题,或者将他保存到数组中。 您可以根据需要使用此代码。

      import json
      
      def parse_object_pairs(pairs):
          """
          This function get list of tuple's
          and check if have duplicate keys.
          if have then return the pairs list itself.
          but if haven't return dict that contain pairs.
      
          >>> parse_object_pairs([("color": "red"), ("size": 3)])
          {"color": "red", "size": 3}
      
          >>> parse_object_pairs([("color": "red"), ("size": 3), ("color": "blue")])
          [("color": "red"), ("size": 3), ("color": "blue")]
      
          :param pairs: list of tuples.
          :return dict or list that contain pairs.
          """
          dict_without_duplicate = dict()
          for k, v in pairs:
              if k in dict_without_duplicate:
                  return pairs
              else:
                  dict_without_duplicate[k] = v
      
          return dict_without_duplicate
      
      decoder = json.JSONDecoder(object_pairs_hook=parse_object_pairs)
      
      str_json_can_be_with_duplicate_keys = '{"color": "red", "size": 3, "color": "red"}'
      
      data_after_decode = decoder.decode(str_json_can_be_with_duplicate_keys)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-09-24
        • 1970-01-01
        • 2014-06-22
        • 1970-01-01
        • 2023-04-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多