![](/img/trans.png)
[英]Python - Best way to replace an element in a list with a key value from a dictionary
[英]Python best way to assume a value from dictionary?
我正在從外部來源閱讀字典,例如
data = {'name': 'James', 'gender': 'male'}
有時
data = {'name': 'James', 'gender': 'male', 'article': {'title':'abc'}}
有時
data = {'name': 'James', 'gender': 'male', 'article': None}
我不確定不確定數據中是否存在articles
時可以使用.get(key, default)
:
articles = data.get('article', {}).get('title')
但是有時,它們為元素提供了None
值,因此上述內容不起作用並導致錯誤,需要變為:
articles = data.get('article') or {}
但這需要我將其分成2條語句,而不是像前面提到的那樣從文章中獲取值。
有沒有更優雅的方法可以做到這一點,例如:
data.get('article', {}, ignore=[None])
要么
data.get_ignore_none('article', {})
默認情況下,如果鍵不存在, .get()
將返回None
。 您的情況是要返回一個空字典。
現在,我不知道發生了什么錯誤,但是我可以確定它是來自get_stuff(article)
而不是您的列表理解。
您可以通過以下幾種方法解決此問題:
修改get_stuff
,使其直接獲取值,而不是每個元素。 這樣,您只是將它傳遞給[get_stuff(value) for value in data.get('articles')]
。 現在,在get_stuff
,您只需執行以下操作:
def get_stuff(foo): if not foo: return None for item in foo: do stuff return normal_results
在列表理解中添加一個過濾器:
[get_stuff(foo) for foo in data.get('articles') if data.get('articles')]
在這種情況下,使用異常盡早爆發沒有什么錯。 我假設無論數據是什么,都想要標題值或“無”。 以下功能將起作用(對於Python 3)。
def get_title(d):
try:
return data.get("article").get("title")
except AttributeError:
return None
如果外部字典獲得None作為值,或者默認情況下,它將在您剛剛捕獲的None對象上引發AttributeError。
首先,您似乎認為使用or
表達式來丟棄data.get('article')
false-y結果只能在以下兩條語句中完成:
temp = data.get('article') or {}
articles = temp.get("title")
但是,您可以將括號放在第一個表達式周圍,然后直接在其返回值上調用.get("title")
:
articles = (data.get('article') or {}).get("title")
但是我覺得這不是特別可讀或有效,當缺少'article'
或“ None
您正在創建一個新的映射並不必要地檢查它的"title"
。
一種可能的解決方案是使用如下函數:
def nested_get(mapping, *keys):
"""gets a value from a nested dictionary,
if any key along the way is missing or None then None is returned
will raise an AttributeError if a value in the chain is not a dictionary (support the .get method)"""
current = mapping
for item in keys:
current = current.get(item)
if current is None:
return None
return current
然后,您將執行nested_get(data, "article", "title")
來嘗試獲取data["article"]["title"]
,如果data["article"]
為None或丟失則不會引發錯誤。
我使用以下代碼對此進行了測試:
test_cases = [{'name': 'James', 'gender': 'male'},
{'name': 'James', 'gender': 'male', 'article': {'title':'abc'}},
{'name': 'James', 'gender': 'male', 'article': None}]
for case in test_cases:
print(case)
print(nested_get(case,"article","title"))
print()
#the follwing will raise an error since mapping["a"] would need to be a dict
nested_get({"a":5}, "a","b")
這個怎么樣
>>> data = {1:(42,23)}
>>> [x for x in data.get(1) or []]
[42, 23]
>>> [x for x in data.get(32) or []]
[]
使用or
更改為默認值,以防萬一您得到None
或等同於false的信息
編輯 :
以相同的方式,您可以將or
和括起來,以在一行中獲得所需的輸出
articles = (data.get('article') or {}).get('title')
只需處理所有3種情況即可。
您還可以例如定義get_ignore_none
def get_ignore_none(data_dict, key, default=None):
if key in data_dict:
value = data_dict[key]
return value if value is not None else default
return default
由於您是從外部來源加載此數據,因此一種方法是在您加載后立即進行預處理:
from collections import Mapping
def remove_none(d):
for k, v in d.items():
if v is None:
del d[k]
if isinstance(v, Mapping):
remove_none(v)
data = load_data_from_somewhere()
remove_none(data)
現在,您可以隨處使用get
來進行以下操作:
articles = data.get('article', {}).get('title')
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.