2
我有一個包含其他字典和列表像這樣一類JSON詞典:Python的可變對象,並且當複製它們
"A": {
"attrib2": "bar",
"attrib1": "foo",
"B": "b",
"C": [
"c1",
"c2"
],
"D": [
{
"attrib3": "baz"
},
{
"attrib4": "muh"
}
]
}
每個值可以是一個列表(dictonaries或值),字典或一個不可變的值(如「c1」或5)。
現在我想搜索特定的值,我通過所需的鍵來引用它們([「A」,「B」]將指向值「b」)。由於在鍵的給定路徑中可能有列表,我將返回所有找到的值。我的功能如下所示:
def getValues(inputDict, keyList):
"""
works on dicts in json-like format as outputted by complexXmlElement2dict
"""
values = list()
if keyList:
key = keyList.pop(0)
try:
currentValue = inputDict[key]
except KeyError:
logger.debug("could not find key {}".format(key))
return list()
if isinstance(currentValue, dict):
additionalValues = getValues(copy.deepcopy(currentValue), list(keyList)) # copy list and dict!!
values.extend(additionalValues)
elif isinstance(currentValue, list):
for subDict in currentValue:
assert isinstance(subDict, dict)
values.extend(getValues(copy.deepcopy(subDict), list(keyList))) # copy list and dict!!
else:
values.append(currentValue)
return list(values)
正如你所看到的,我對這裏使用的可變對象有些偏執。我正在複製留下的鍵列表以查找正確的值以及我每次使用的字典。我的函數按預期工作,但我認爲由於不必要地複製所有這些對象而造成大量開銷。
什麼時候可以省略複製這個例子中的字典和列表,爲什麼?試錯法是沒有選擇的,因爲我沒有所有可能的輸入字典,也因爲我想獲得更好的理解。我應該補充一點,我已經閱讀了很多python中的可變對象的例子和解釋,儘管我認爲我理解了我覺得不夠舒服的概念,但是我認爲這是不必要的,因爲其他人依賴於此代碼的正確性。
getValues(copy.deepcopy(currentValue), list(keyList))
getValues(copy.deepcopy(subDict), list(keyList)))
return list(values)
我正在使用Python 2.7。
我的keyList每次更深一層時都會更新:key = keyList.pop(0),每當我找到一個匹配搜索模式的值時,我的值列表就會更新。字典currentValue也指向每次大字典的不同部分。 – Stefan
關於按鍵列表,您可以每次通過同一列表並傳遞索引以確定要處理的密鑰。關於字典currentValue,它指向不同的大字典並不重要,如果你沒有更新它,你可以使用淺拷貝。無需深層複製。關於價值清單,您總是創建一個新清單,並將其追加到前一個清單中。你需要理解遞歸函數的概念。 –