Python 3.5关于嵌套dict数据的if语句:TypeError
代码: 我可能完全弄错了,但仍在尝试学习json/dict迭代以及如何在多个迭代之间进行比较 我正在尝试从与相同epic ID匹配的故事中检索数据。我知道Python 3.5关于嵌套dict数据的if语句:TypeError,python,if-statement,for-loop,dictionary,Python,If Statement,For Loop,Dictionary,代码: 我可能完全弄错了,但仍在尝试学习json/dict迭代以及如何在多个迭代之间进行比较 我正在尝试从与相同epic ID匹配的故事中检索数据。我知道故事['epic']包含['ID']和['local\u ID'],但显然我无法将其与非故事dict数据进行比较 注意:story['epic']['id']的值可以为空。大多数JSON库将其输入转换为嵌套的dicts。然而,除非源代码非常友好,否则在处理JSON输入时,您几乎总是要处理对象可能被忽略的事实 处理此问题的最佳方法是使用dict.
故事['epic']
包含['ID']
和['local\u ID']
,但显然我无法将其与非故事dict数据进行比较
注意:
story['epic']['id']
的值可以为空。大多数JSON库将其输入转换为嵌套的dict
s。然而,除非源代码非常友好,否则在处理JSON输入时,您几乎总是要处理对象可能被忽略的事实
处理此问题的最佳方法是使用dict.get()
而不是直接订阅生成的dict
,因为它允许您在缺少密钥时提供默认值
因此,您可以做的不是story['epic']['id']
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'])
这将返回故事的id
值(如果存在),或者返回空字符串。无论哪种方式,您都可以安全地将其与epic['id']
请注意,所有中间步骤都应返回一个空的dict
,作为默认值-允许调用链在不引发异常的情况下继续
story_id = story.get('epic', {}).get('id', "")
如果您发现自己在足够多的地方做这件事,看起来很重复(而且您会:),那么您总是可以将其抽象为一个实用函数
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)
这也就是说
story['epic']
是一个无对象或
epic['id']
是一个无对象
那么错误消息现在就有意义了,您应该能够在代码的逻辑中找出原因。错误消息告诉您,
story
、story['epic'
]或epic
等于None
;您可以先找出问题所在。如果story
或store['epic']
是None
,则可以在有问题的之前插入print(story)
和print(story)
来查找问题,因此下一个[…]
表达式的一部分应用于该对象,而不是字典。你必须弄清楚是哪一个,以及如何处理这个问题。哦,所以实际的列表可能在story或story['epic']中没有。好的,这是一个好的开始。这与上面Martijn的评论有何不同?@kdopen-我没有读到评论。评论是为了澄清而不是回答。:)这对工作很有帮助。感谢您澄清实用程序函数示例。我目前有7个地方重复这一点,这样应该有助于减少代码更改。
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')