0

複合辞書の1つの項目を変更する関数が必要です。私は次のようなことを試しました。

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
  1. 自己パラメータがありません
  2. あなたが持っている作業コードの行を使用するだけです。
  3. あなたが主張するなら、ここに方法があります:

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

明らかに、キーのリストが dict 以外の値にヒットすると、これは壊れます。あなたはそれを処理したいと思うでしょう。実際には、その理由から明示的なループの方がおそらく優れているでしょうが、その考えは理解できます。

于 2012-09-18T20:43:06.263 に答える
2
setItem = lambda self,names,value: map((lambda name: setattr(self,name,value)),names)
于 2012-09-18T20:42:12.050 に答える
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 には再帰制限があるため、これは任意にネストされた dict では機能しません。また、パフォーマンスが非常に重要な状況には適していません (Python の再帰は通常そうではありません)。reduceそれにもかかわらず、これらの 2 つの状況以外では、これはorを含むものよりもいくらか明確であることがわかりますlambda

于 2012-09-18T21:51:33.947 に答える