代码之家  ›  专栏  ›  技术社区  ›  odysseus

基于1-2个公共键值获取4个JSON文件的交集?(蟒蛇)

  •  1
  • odysseus  · 技术社区  · 4 年前

    以下是4个JSON文件:

    • 3个JSON文件有3个关键字段:name、rating和year
    • 1 JSON只有两个关键字段:名称、评级(无年份)
    [
      {
        "name": "Apple",
        "year": "2014",
        "rating": "21"
      },
      {
        "name": "Pear",
        "year": "2003",
        "rating": ""
      },
      {
        "name": "Pineapple",
        "year": "1967",
        "rating": "60"
      },
    ]
    
    [
      {
        "name": "Pineapple",
        "year": "1967",
        "rating": "5.7"
      },
      {
        "name": "Apple",
        "year": "1915",
        "rating": "2.3"
      },
      {
        "name": "Apple",
        "year": "2014",
        "rating": "3.7"
      }
    ]
    
    [
      {
        "name": "Apple",
        "year": "2014",
        "rating": "2.55"
      }
    ]
    
    [
      {
        "name": "APPLE",
        "rating": "+4"
      },
      {
        "name": "LEMON",
        "rating": "+3"
      }
    ]
    

    在所有4个文件中搜索“Apple”时,您希望返回1个名称、1年和4个评级:

    name: Apple (closest match to search term across all 4 files)
    year: 2014 (the MOST COMMON year for Apple across first 3 JSONs)
    rating:  21 (from JSON1)
            3.7 (from JSON2)
           2.55 (from JSON3)
             +4 (from JSON4)
    

    现在假设JSON3(或任何JSON)已经 不匹配 相反 返回以下内容。假设在至少一个文件中至少有一个匹配项。

    name: Apple (closest match to search term across all 4 files)
    year: 2014 (the MOST COMMON year for Apple across first 3 JSONs)
    rating:  21 (from JSON1)
            3.7 (from JSON2)
      Not Found (from JSON3)
             +4 (from JSON4)
    

    如何在Python中获得这个输出?

    此问题类似于中的示例代码 Python - Getting the intersection of two Json-Files ,除了有4个文件外,还有1个文件缺少 评级

    到目前为止,我只得到了上面两组JSON:

    import json
    
    with open('1.json', 'r') as f:
      json1 = json.load(f)
    
    with open('2.json', 'r') as f:
      json2 = json.load(f)
    
    json2[0]['name'] = list(set(json2[0]['name']) - set(json1[0]['name']))
    
    print(json.dumps(json2, indent=2))
    

    我从中得到了输出,但它与我想要达到的目标不匹配。例如,这是输出的一部分:

      {
        "name": [
          "a",
          "n",
          "i",
          "P"
        ],
        "year": "1967",
        "rating": "5.7"
      },
    
    0 回复  |  直到 4 年前
        1
  •  0
  •   EliKor    4 年前

    当您使用 set 构造函数中,它需要一个iterable对象,并将遍历该对象的值来生成您的集合。所以,当你试图直接从一个字符串中创建一个集合时,你最终会得到

    name = set('Apple')
    # name = {'A', 'p', 'p', 'l', 'e'}
    

    因为字符串是由字符组成的可iterable对象。相反,您可能希望将字符串包装成一个列表或元组,如下所示

    name = set(['Apple'])
    # name = {'Apple'}
    

    在你的情况下

    json2[0]['name'] = list(set([json2[0]['name']]) - set([json1[0]['name']]))
    

    但我仍然不认为这是你真正想要实现的。相反,我建议您遍历每个json文件,生成自己的字典,根据json文件中的名称编制索引。字典中的每个值都会有另一个带有两个键的字典, rating year ,两者都有一个值列表。一旦你建立了你的字典,你将得到每个名字的等级和年份列表,然后你可以通过选择年份列表中最频繁的年份将每个年份列表转换成一个值。 这里有一个例子说明你的字典可能是什么样子

    {
      "Apple": { "rating": [21, 3.7, ...], "year": [1915, 2014, 2014] }
      "Pineapple": ...
      ...
    }