2

以下は、私が信じている方法で機能します。

dictionary = {'k1': {'a': 'b'}, 'k2': [0, 1]}  
pointer = dictionary['k1']  
print pointer  
>>> {'a': 'b'}  
pointer.update({'a': 'c'})  
print dictionary  
>>> {'k1': {'a': 'c'}, 'k2': [0, 1]} 

以下は私を苛立たせます:

pointer = dictionary['k2']
print pointer
>>> [0, 1]
pointer.update([2, 3])
>>> AttributeError: 'list' object has no attribute 'update'  

リストには更新機能がないことを認識しており、次のようなことができることを理解しています。

pointer[0] = 2

...しかし、参照値を更新するためのより普遍的なオプションが欲しいので、オブジェクトはまだ辞書に属していますが、値は変更されています。

この理由は、次のようなネストされた辞書を持っているためです。

dictionary['key']['key']['key']['key'] 

私の質問は、リストに更新機能があるかどうかを目的としたものではありません-むしろ、深くネストされた辞書内の値を参照および変更するよりクリーンな方法があるかどうかを尋ねているので、それを参照値に格納する方が目に優しいでしょう何かを割り当てるたびにすべてを入力するのではなく、

ありがとう!

EDIT: 最初の例の構文を修正しました EDIT2:
はっきりさせてください: リストには機能がないことは承知していますがupdate、むしろ普遍的な参照値の更新について質問しています
EDIT3: 簡単な質問です

4

4 に答える 4

5

そのようなことはない。参照は、オブジェクト内の場所ではなく、オブジェクトを指します。限目。これは、Python オブジェクト モデルの基本的な部分です。

気が向いたら、そのような場所を表すクラスを書くことができます:

class AttributeReference:
    def __init__(self, obj, attr):
        self.obj = obj
        self.attr = attr

    def set(self, value):
        setattr(self.obj, self.attr, value)

    # add get() and del() and other methods to your heart's content 


class ElementReference:
    def __init__(self, obj, key):
        self.obj = obj
        self.key = key

    def set(self, value):
        self.obj[self.key] = value

    # add get() and del() and other methods to your heart's content

その後、Python 参照の代わりにそのようなオブジェクトを使用できます。ただし、かなり扱いにくいので、使用のハードルはかなり高くなります。明るい面では、入れ子の深さはまったく関係ありません。への「参照」が必要な場合はdictionary['k1']['k2']['k3']['k4']、次のようにしますElementReference(dictionary['k1']['k2']['k3'], 'k4')

于 2014-09-17T21:10:36.917 に答える
3

エラー メッセージから明らかなように、 a にはメソッドlistがありませんupdate。これは、その内容を変更できないという意味ではなく、別の方法で変更する必要があるだけです。

pointer[:] = [2, 3]

普遍的な更新機能を作成できますが、それがどれほど役立つかはわかりません。

def update(pointer, values):
    if isinstance(pointer, list):
        pointer[:] = values
    else:
        pointer.update(dict(values))

編集:あなたは本当にリーフノードの更新にしか興味がないように見えるので、なぜ以下が十分ではなかったのかわかりません。可変オブジェクトに設定されている限り、pointerそのオブジェクトを変更でき、元の辞書でも変更されます。唯一できないことは、参照を再割り当てし、辞書への接続を切断するため、直接再割り当てすることです。

pointer = dictionary['key1']['key2']['key3']['key4']
# pointer = [2, 3]   # doesn't work
pointer[:] = [2, 3]  # works
print dictionary['key1']['key2']['key3']['key4']
于 2014-09-17T21:02:08.977 に答える
1

あなたの質問を完全に理解しているかどうかはまだわかりませんが、ここに2つのアプローチがあります。次のような dict があるとします。

d = {'level1': {'level2': {'level3': {'level4': [1, 2, 3]}}}}

d['level1']['level2']['level3']['level4']最も内側のリストへの参照を提供します。それを保存すれば、それで好きなことをすることができます:

innerValue = d['level1']['level2']['level3']['level4']
innerValue.append(4)

>>> d
{'level1': {'level2': {'level3': {'level4': [1, 2, 3, 4]}}}}

ただし、他の人がコメントで指摘しているように、ここで変更しているのはlistです。リストは、それが辞書の中にあることを「認識」していません。そのリストに対してできることは、他のリストに対してできることと同じです。それがリストではなく他の種類のオブジェクトである場合、同じことが当てはまります。それが辞書内にあるときにできることは、他の場所でできることと同じです。オブジェクトをその場で更新したい場合、辞書にはそれが通知されません。したがって、オブジェクトが辞書内にあるかどうかがわからないため、オブジェクトが辞書内にあるという事実に基づいた「ユニバーサル」な更新方法を持つ方法はありません。

別の方法は、変更する要素を含む辞書への参照を保存することです。次に、通常の dict 操作を使用してその値を変更できます。

innerDict = d['level1']['level2']['level3']
innerDict['level4'] = "Some other value"

>>> d
{'level1': {'level2': {'level3': {'level4': 'Some other value'}}}}

このメソッドは、その内部辞書に格納されている値の種類に依存しないという意味で「ユニバーサル」です。そこで起こっているのは、その値が新しいオブジェクトを指すように、その内部辞書を更新していることです。ただし、これは新しいオブジェクトを作成するため、元のリストをその場で変更しないことに注意してください (また、私の例のように、値の型を変更することさえできます)。内部の dict をインプレースで変更します (キーの 1 つに新しい値を割り当てることにより)。

あなたの質問から何を達成しようとしているのかは明らかではありませんが、これらは、深くネストされた dict に何かへの何らかの参照を格納し、それをいじる 2 つの方法です。

于 2014-09-17T21:22:30.810 に答える