提问人:Stefan 提问时间:8/11/2017 更新时间:8/11/2017 访问量:469
Python 可变对象以及何时复制它们
Python Mutable Objects and when to copy them
问:
我有一个类似json的词典,其中包含其他词典和列表,如下所示:
"A": {
"attrib2": "bar",
"attrib1": "foo",
"B": "b",
"C": [
"c1",
"c2"
],
"D": [
{
"attrib3": "baz"
},
{
"attrib4": "muh"
}
]
}
每个值可以是列表(字典或值)、字典或不可变值(如“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。
答:
0赞
Mukesh Kumar
8/11/2017
#1
我找不到任何理由复制字典或列表。您没有更新其中任何一个。您只是从中提取数据。因此,只需在递归函数中传递引用即可。
评论
0赞
Stefan
8/11/2017
每次我深入一级时,我的 keyList 都会更新:key = keyList.pop(0),每次我找到与搜索模式匹配的值时,我的值列表都会更新。字典 currentValue 每次也指向大字典的不同部分。
0赞
Mukesh Kumar
8/11/2017
关于键列表,您可以每次传递相同的列表并传递索引以标识要处理的键。关于字典currentValue,它是否指向不同的大字典并不重要,如果你不更新它,你可以使用浅拷贝。无需深度复制。关于值列表,您始终在创建一个新列表,并将其附加到上一个列表中。您需要了解递归函数的概念。
评论