Mit*_*ops 24 python dictionary list-comprehension
我正在使用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")
Run Code Online (Sandbox Code Playgroud)
但是,有时其中一个"父"或"子"标签不存在,我的脚本失败.我知道使用get()我可以在表格中不存在密钥的情况下包含默认值...
get("parent", '') or
get("parent", 'orphan')
Run Code Online (Sandbox Code Playgroud)
但是,如果我包含任何Null,''或者我可以想到的空,则链接.get("child")在调用时失败,''.get("child")因为""没有方法.get().
现在我解决这个的方法是使用一束连续的try-except围绕每个.get("")电话,但似乎愚蠢和unpython ---有没有办法为默认的回报"skip"或"pass"什么的,将仍然支持链接和失败智能,而不是深 - 潜入不存在的钥匙?
理想情况下,我希望这是对表单的列表理解:
[m.get("gparents").get("parent").get("child") for m in M]
Run Code Online (Sandbox Code Playgroud)
但是当缺席的父母导致.get("child")呼叫终止我的程序时,这当前是不可能的.
Mar*_*ers 68
因为这些都是python dict并且你dict.get()在它们上面调用方法,所以你可以使用一个空dict来链:
[m.get("gparents", {}).get("parent", {}).get("child") for m in M]
Run Code Online (Sandbox Code Playgroud)
通过不使用最后一个的默认值,.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???
Run Code Online (Sandbox Code Playgroud)
就像Martijn的回答一样,这并不保证X可迭代(非None).虽然,你可以通过使get链中的最后一个默认返回一个空列表来解决这个问题:
try:
X = m.get("gparents").get("parent").get("child",[])
except AttributeError:
continue
Run Code Online (Sandbox Code Playgroud)
最后,我认为这个问题的最佳解决方案可能是使用reduce:
try:
X = reduce(dict.__getitem__,["gparents","parent","child"],m)
except (KeyError,TypeError):
pass
else:
for x in X:
#do something with x
Run Code Online (Sandbox Code Playgroud)
这里的优点是您可以get根据引发的异常类型知道是否有任何失败.a可能get返回错误的类型,然后你得到一个TypeError.如果字典没有密钥,它会引发一个KeyError.您可以单独或一起处理这些.哪种最适合您的用例.
我意识到我有点晚了,但这是我在遇到类似问题时提出的解决方案:
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)
Run Code Online (Sandbox Code Playgroud)
例如:
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
Run Code Online (Sandbox Code Playgroud)
使用一个小的辅助函数怎么样?
def getn(d, path):
for p in path:
if p not in d:
return None
d = d[p]
return d
Run Code Online (Sandbox Code Playgroud)
进而
[getn(m, ["gparents", "parent", "child"]) for m in M]
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
12946 次 |
| 最近记录: |