繁体   English   中英

链接,嵌套的dict()在python中调用

[英]Chained, nested dict() get calls in python

我正在使用dict.get('keyword')方法查询嵌套字典。 目前我的语法是......

M = cursor_object_results_of_db_query

for m in M:
    X = m.get("gparents").get("parent").get("child")
    for x in X:
        y = x.get("key")

但是,有时其中一个“父”或“子”标签不存在,我的脚本失败。 我知道使用get()我可以在表格中不存在键的情况下包含默认值...

get("parent", '') or
get("parent", 'orphan') 

但是如果我包含任何Null''或者我可以想到的空,则链接.get("child")在调用''.get("child") .get("child")失败,因为""没有方法.get()

我现在解决这个问题的方法是使用一堆顺序try-except围绕每个.get("")调用,但这看起来很愚蠢和unpython ---有没有办法默认返回"skip""pass"或者仍然支持链接并且智能地失败的东西,而不是深入研究不存在的密钥?

理想情况下,我希望这是对表单的列表理解:

[m.get("gparents").get("parent").get("child") for m in M]

但是当缺席的父母导致.get("child")调用终止我的程序时,这是不可能的。

因为这些都是python dict并且你在它们上面调用dict.get()方法,你可以使用一个空的dict来链接:

[m.get("gparents", {}).get("parent", {}).get("child") for m in M]

通过不使用最后一个.get()的默认值,您将回退到None 现在,如果找不到任何中间密钥,则链的其余部分将使用空字典查找内容,以.get('child')结尾返回None

另一种方法是识别如果找不到密钥,则dict.get返回None 但是, None没有属性.get ,因此会抛出AttributeError

for m in M:
    try:
       X = m.get("gparents").get("parent").get("child")
    except AttributeError:
       continue

    for x in X:
        y = x.get("key")
        #do something with `y` probably???

就像Martijn的回答一样,这并不能保证X是可迭代的(非None )。 虽然,你可以通过使链中的最后一个get默认返回一个空列表来解决这个问题:

 try:
    X = m.get("gparents").get("parent").get("child",[])
 except AttributeError:
    continue

最后,我认为这个问题的最佳解决方案可能是使用reduce

try:
    X = reduce(dict.__getitem__,["gparents","parent","child"],m)
except (KeyError,TypeError):
    pass
else:
    for x in X:
       #do something with x

这里的优点是你get根据引发的异常类型知道任何get失败。 get可能返回错误的类型,然后得到TypeError 但是,如果字典没有密钥,则会引发KeyError 您可以单独或一起处理这些。 哪种最适合您的用例。

如何使用小帮手功能?

def getn(d, path):
    for p in path:
        if p not in d:
            return None
        d = d[p]
    return d

接着

[getn(m, ["gparents", "parent", "child"]) for m in M]

我意识到我有点迟到了,但这是我遇到类似问题时提出的解决方案:

def get_nested(dict_, *keys, default=None):
    if not isinstance(dict_, dict):
        return default
    elem = dict_.get(keys[0], default)
    if len(keys) == 1:
        return elem
    return get_nested(elem, *keys[1:], default=default)

例如:

In [29]: a = {'b': {'c': 1}}
In [30]: get_nested(a, 'b', 'c')
Out[30]: 1
In [31]: get_nested(a, 'b', 'd') is None
Out[31]: True

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM