【问题标题】:Python 3.5 if statement on nested dict data : TypeErrorPython 3.5 if 嵌套字典数据的语句:TypeError
【发布时间】:2016-05-21 07:56:29
【问题描述】:
if story['epic']['id'] == epic['id']:

TypeError: 'NoneType' object is not subscriptable

代码:

for epic in epics:
    if epic['archived'] is False:
        print(epic['short_name'], epic['summary'], epic['story_count'])
        for story in stories:
            if story['epic']['id'] == epic['id']:
                    print(story['summary'], story['cell']['label'])

我可能搞错了,但仍在尝试学习 json/dict 迭代以及如何在多个迭代之间进行比较。

我正在尝试从将 ID 与同一史诗 ID 匹配的故事中检索数据。我知道story['epic'] 下包含['id']['local_id'],但显然我无法将其与非故事字典数据进行比较?

注意:story['epic']['id'] 的值可以为空。

【问题讨论】:

  • 错误信息告诉你storystory['epic']或epic等于None;你可以从找出它是什么开始。
  • 你可以通过在有问题的if之前插入print(epic)print(story)来找到问题
  • storystore['epic']None,因此表达式的下一个 [...] 部分应用于该对象而不是字典。您必须弄清楚是哪一个以及如何处理。
  • 哦,所以实际的列表可能在故事或故事['epic'] 中没有。好的,这是一个好的开始。

标签: python if-statement for-loop dictionary


【解决方案1】:

大多数 JSON 库将其输入转换为嵌套的 dicts。但是,除非来源非常友好,否则在处理 JSON 输入时,您几乎总是必须处理对象可能被省略的事实。

处理此问题的最佳方法是使用dict.get(),而不是直接下标生成的dict,因为它允许您在缺少密钥时提供默认值。

因此,您可以使用 story['epic']['id'] 代替

story_id = story.get('epic', {}).get('id', "")

这将返回故事的id 值(如果存在)或空字符串。无论哪种方式,您都可以放心地将其与 epic['id']

进行比较

请注意,所有中间步骤都应返回一个空的 dict 作为默认值 - 允许调用链继续而不引发异常。

mydict.get('k1',{}).get('k1.1',{}).get('k1.1.1`,{}).get('lastkey','default')

如果您发现自己在足够多的地方执行此操作似乎重复(并且您会:)您总是可以将其抽象为实用函数

def getnested(thedict,intermediate_keys,final_key,dflt):
    dd = thedict
    for key in intermediate_keys:
        dd = dd.get(key,{})
    return dd.get(final_key,dflt)

这样称呼它

getnested(story,['epic'], 'id', 'missing')
getnested(mydict,['k1','k1.1','k1.1.1'],'lastkey','default')

【讨论】:

  • 非常有助于使其正常工作。感谢您澄清实用功能示例。我目前有 7 个地方正在重复,这应该有助于减少代码更改。
【解决方案2】:

这只是意味着,要么

story['epic'] 是无对象或 epic['id'] 是一个无对象。

那么现在错误消息是有意义的,您应该能够从代码的逻辑中找出原因。

【讨论】:

  • 这与上面 Martijn 的评论有何不同?
  • @kdopen - 我没有阅读评论。评论是为了澄清而不是回答。 :)
猜你喜欢
  • 1970-01-01
  • 2018-07-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-01
  • 1970-01-01
  • 2021-11-18
  • 1970-01-01
相关资源
最近更新 更多