python 当需要嵌套字典时,.json文件中的字典返回空

pvabu6sv  于 2023-10-14  发布在  Python
关注(0)|答案(2)|浏览(128)

我应该运行一段代码,用函数get_affiliation_prizes(dict_laureates)查找诺贝尔奖赢家的所有从属关系。这是数据结构的一个例子:

{'id': '2',
   'firstname': 'Hendrik A.',
   'surname': 'Lorentz',
   'born': '1853-07-18',
   'died': '1928-02-04',
   'bornCountry': 'the Netherlands',
   'bornCountryCode': 'NL',
   'bornCity': 'Arnhem',
   'diedCountry': 'the Netherlands',
   'diedCountryCode': 'NL',
   'gender': 'male',
   'prizes': [{'year': '1902',
     'category': 'physics',
     'share': '2',
     'motivation': '"in recognition of the extraordinary service they rendered by their researches into the influence of magnetism upon radiation phenomena"',
     'affiliations': [{'name': 'Leiden University',
       'city': 'Leiden',
       'country': 'the Netherlands'}]}]},
  {'id': '3',
   'firstname': 'Pieter',
   'surname': 'Zeeman',
   'born': '1865-05-25',
   'died': '1943-10-09',
   'bornCountry': 'the Netherlands',
   'bornCountryCode': 'NL',
   'bornCity': 'Zonnemaire',
   'diedCountry': 'the Netherlands',
   'diedCountryCode': 'NL',
   'diedCity': 'Amsterdam',
   'gender': 'male',
   'prizes': [{'year': '1902',
     'category': 'physics',
     'share': '2',
     'motivation': '"in recognition of the extraordinary service they rendered by their researches into the influence of magnetism upon radiation phenomena"',
     'affiliations': [{'name': 'Amsterdam University',
       'city': 'Amsterdam',
       'country': 'the Netherlands'}]}]},

这是我写的代码:

def get_affiliation_prizes(dict_laureates):
    affiliation_prizes = {}
    for laureate in dict_laureates:
        if 'prizes' in laureate and 'affiliations' in laureate:
            for prize in laureate['affiliations']:
                category = prize.get('category')
                year = prize.get('year')
                if category and year:
                    affiliation_prizes[affiliation].append({'category': category, 'year': year})
    return affiliation_prizes
    

with open('../Data/json_data/NobelPrize/laureate.json', 'r', encoding='utf-8') as file:
    dict_laureates = json.load(file)

affiliation_prizes = get_affiliation_prizes(dict_laureates)
print(affiliation_prizes)

但是,它总是返回一个空字典
我尝试了一下if语句,看看删除或添加一些条件是否有帮助,但它要么破坏了代码,要么仍然返回一个空字典。
我期望发生的(或者说希望发生的)是以以下格式返回嵌套字典的代码:

{
    "A.F. Ioffe Physico-Technical Institute": [
        {"category": "physics", "year": "2000"}
    ],
    "Aarhus University": [
        {"category": "chemistry", "year": "1997"},
        {"category": "economics","year": "2010"}
    ]
}

奥胡斯大学应该有两本字典的方式是(我相信),因为它们是两个诺贝尔奖的附属机构:

{'id': '857',
   'firstname': 'Dale T.',
   'surname': 'Mortensen',
   'born': '1939-02-02',
   'died': '2014-01-09',
   'bornCountry': 'USA',
   'bornCountryCode': 'US',
   'bornCity': 'Enterprise, OR',
   'diedCountry': 'USA',
   'diedCountryCode': 'US',
   'diedCity': 'Wilmette, IL',
   'gender': 'male',
   'prizes': [{'year': '2010',
     'category': 'economics',
     'share': '3',
     'motivation': '"for their analysis of markets with search frictions"',
     'affiliations': [{'name': 'Northwestern University',
       'city': 'Evanston, IL',
       'country': 'USA'},
      {'name': 'Aarhus University',
       'city': 'Aarhus',
       'country': 'Denmark'}]}]},

{'id': '289',
       'firstname': 'Jens C.',
       'surname': 'Skou',
       'born': '1918-10-08',
       'died': '2018-05-28',
       'bornCountry': 'Denmark',
       'bornCountryCode': 'DK',
       'bornCity': 'Lemvig',
       'diedCountry': 'Denmark',
       'diedCountryCode': 'DK',
       'diedCity': 'Aarhus',
       'gender': 'male',
       'prizes': [{'year': '1997',
         'category': 'chemistry',
         'share': '2',
         'motivation': '"for the first discovery of an ion-transporting enzyme, Na+, K+ -ATPase"',
         'affiliations': [{'name': 'Aarhus University',
           'city': 'Aarhus',
           'country': 'Denmark'}]}]},
r6hnlfcb

r6hnlfcb1#

你的代码遇到了一个错误,所以你永远无法深入研究它以找到其他错误。
您的函数应该进一步深入研究每个prize中的'affiliations'键:

def get_affiliation_prizes(dict_laureates):
    affiliation_prizes = {}
    for laureate in dict_laureates:
        if 'prizes' in laureate:
            for prize in laureate['prizes']:
                if 'affiliations' in prize:
                    category = prize.get('category')
                    year = prize.get('year')
                    if category and year:
                        for affiliation in prize['affiliations']:
                            affiliation_name = affiliation['name']
                            prizes = affiliation_prizes.get(affiliation_name, None)
                            if not prizes:
                                affiliation_prizes[affiliation_name] = []
                            affiliation_prizes[affiliation_name].append({'category': category, 'year': year})
    return affiliation_prizes
o7jaxewo

o7jaxewo2#

https://jsonlint.com/这样的验证器中检查JSON。
还要注意,随着代码变大,嵌套结构不容易维护。为了避免过多的嵌套,使用continue退出for循环的当前迭代的执行。根据经验,最好尽早测试执行是否必须在循环和函数中继续。
您还应该检查要读取的所有字段是否都存在。如果没有,你应该决定做什么,例如返回一个空字符串或什么都不做。
还请注意,您调用了函数get_affiliation_prizes,但实际上它应该是get_laureate_affiliations

import json
from pprint import pprint

def get_laureate_affiliations(dict_laureates):
    laureate_affiliations = []
    for laureate in dict_laureates:
        if "prizes" not in laureate:
            continue
        for prize in laureate["prizes"]:
            if "affiliations" not in prize:
                continue
        for prize in laureate["prizes"]:
            for affiliation in prize["affiliations"]:
                affiliation_name = affiliation["name"] if "name" in affiliation else ""
                prize_category = prize["category"] if "category" in prize else ""
                prize_year = prize["year"] if "year" in prize else ""
                laureate_affiliation = {
                    affiliation_name: {"category": prize_category, "year": prize_year}
                }
                laureate_affiliations.append(laureate_affiliation)
    return laureate_affiliations

def main():
    with open("laureate.json", "r", encoding="utf-8") as file:
        dict_laureates = json.load(file)
    affiliation_prizes = get_laureate_affiliations(dict_laureates)
    pprint(affiliation_prizes)

if __name__ == "__main__":
    main()

相关问题