0

我需要一个函数来更改复合字典中的一项。我试过类似的东西..

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,但是这个函数没有效果。

4

4 回答 4

3

几乎。您实际上想要执行以下操作:

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)

不过马尔辛是对的。你真的想加入一些更严格的东西,对丢失的键/丢失的字典进行一些错误处理。

于 2012-09-18T20:39:41.307 回答
2
setItem = lambda self,names,value: map((lambda name: setattr(self,name,value)),names)
于 2012-09-18T20:42:12.050 回答
2
  1. 你没有 self 参数
  2. 只需使用您拥有的工作代码行。
  3. 如果你坚持,这里有一个方法:

    def setitem(self, keys, value):
        reduce(dict.get, # = lambda dictionary, key: dictionary[key]
               keys[:-1], self.dictionary)[keys[-1]] = value
    

显然,如果键列表达到非字典值,这将中断。你会想要处理它。事实上,出于这个原因,一个显式循环可能会更好,但你明白了。

于 2012-09-18T20:43:06.263 回答
1

一个涉及递归和 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 中的递归通常不是)。尽管如此,在这两种情况之外,我发现这比涉及reduceor的事情更明确一些lambda

于 2012-09-18T21:51:33.947 回答