我需要一个函数来更改复合字典中的一项。我试过类似的东西..
def SetItem(keys, value):
item = self.dict
for key in keys:
item = item[key]
item = value
和
SetItem(['key1', 'key2'], 86)
它应该等价于self.dict['key1']['key2'] = 86,但是这个函数没有效果。
我需要一个函数来更改复合字典中的一项。我试过类似的东西..
def SetItem(keys, value):
item = self.dict
for key in keys:
item = item[key]
item = value
和
SetItem(['key1', 'key2'], 86)
它应该等价于self.dict['key1']['key2'] = 86,但是这个函数没有效果。
几乎。您实际上想要执行以下操作:
def set_keys(d, keys, value):
item = d
for key in keys[:-1]:
item = item[key]
item[keys[-1]] = value
或者像这样递归:
def set_key(d, keys, value):
if len(keys) == 1:
d[keys[0]] = value
else:
set_key(d[keys[0]], keys[1:], value)
不过马尔辛是对的。你真的想加入一些更严格的东西,对丢失的键/丢失的字典进行一些错误处理。
setItem = lambda self,names,value: map((lambda name: setattr(self,name,value)),names)
如果你坚持,这里有一个方法:
def setitem(self, keys, value):
reduce(dict.get, # = lambda dictionary, key: dictionary[key]
keys[:-1], self.dictionary)[keys[-1]] = value
显然,如果键列表达到非字典值,这将中断。你会想要处理它。事实上,出于这个原因,一个显式循环可能会更好,但你明白了。
一个涉及递归和 EAFP 的想法,我一直都很喜欢:
def set_item(d, keys, value):
key = keys.pop(0)
try:
set_item(d[key], keys, value)
# IndexError happens when the pop fails (empty list), KeyError happens when it's not a dict.
# Assume both mean we should finish recursing
except (IndexError, KeyError):
d[key] = value
例子:
>>> d = {'a': {'aa':1, 'ab':2}, 'b':{'ba':1, 'bb':2}}
>>> set_item(d, ['a', 'ab'], 50)
>>> print d
{'a': {'aa': 1, 'ab': 50}, 'b': {'ba': 1, 'bb': 2}}
编辑:正如 Marcin 在下面指出的那样,这不适用于任意嵌套的字典,因为 Python 有递归限制。它也不适用于对性能高度敏感的情况(Python 中的递归通常不是)。尽管如此,在这两种情况之外,我发现这比涉及reduce
or的事情更明确一些lambda
。