11

Pythonは初めてですが、私が口述を持っているとしましょう。

kidshair = {'allkids':{'child1':{'hair':'blonde'},
                      'child2':{'hair':'black'},
                      'child3':{'hair':'red'},
                      'child4':{'hair':'brown'}}}

child3が定期的に髪の色を変える場合は、データのメンテナンスを高速化するアプリケーションを作成することをお勧めします。この例では、次を使用します。

kidshair['allkids']['child3']['hair'] = ...

このパスを変数として保存して、レジャーでアクセスできるようにする方法はありますか?明らかに

mypath = kidshair['allkids']['child3']['hair']

結果はmypath='red'になります。パス自体をハードコーディングして使用できるようにする方法はありますか?

mypath = 'blue' 

再現する

kidshair['allkids']['child3']['hair'] = 'blue'

どうもありがとう、ATfPT

4

5 に答える 5

11

必要なものによっては、ネストされた辞書の代わりにタプルを辞書キーとして使用するのが最も簡単なオプションです。

kidshair['allkids', 'child3', 'hair']
mypath = ('allkids', 'child3', 'hair')
kidshair[mypath]

これに関する唯一の問題は、辞書の一部を取得できないことです。そのため、たとえば、に関係するすべてのものに(簡単に/効率的に)アクセスすることはできません'child3'。これは、使用法に応じて、適切なソリューションである場合とそうでない場合があります。

現在の構造の代替手段は、次のようなことを行うことです。

>>> from functools import partial
>>> test = {"a": {"b": {"c": 1}}}
>>> def itemsetter(item):
...     def f(name, value):
...         item[name] = value
...     return f
...
>>> mypath = partial(itemsetter(test["a"]["b"]), "c")
>>> mypath(2)
>>> test
{'a': {'b': {'c': 2}}}

ここで、関数を作成しますitemsetter()。これは、(の静脈内でoperator.itemgetter())指定された辞書に関連するキーを設定する関数を提供します。次に、を使用functools.partialして、事前に入力したいキーを使用してこの関数のバージョンを生成します。どちらでもありませmypath = blueんが、悪くはありません。

モジュールに一貫性のあるものを作成することに煩わされたくない場合は、次のoperatorようにすることができます。

def dictsetter(item, name):
     def f(value):
         item[name] = value
     return f

mypath = dictsetter(test["a"]["b"], "c")

mypath(2)
于 2012-04-29T11:29:49.723 に答える
9

特定の辞書の「パス」にアクセスする一連の関数を作成できます。

def pathGet(dictionary, path):
    for item in path.split("/"):
        dictionary = dictionary[item]
    return dictionary

def pathSet(dictionary, path, setItem):
    path = path.split("/")
    key = path[-1]
    dictionary = pathGet(dictionary, "/".join(path[:-1]))
    dictionary[key] = setItem

使用法:

>>> pathGet(kidshair, "allkids/child1/hair")
'blonde'
>>> pathSet(kidshair, "allkids/child1/hair", "blue")
>>> kidshair['allkids']['child1']
{'hair': 'blue'}
于 2012-04-29T11:55:37.337 に答える
2

kidshair['allkids']['child3']次のへの参照を簡単に保存できます。

thiskid = kidshair['allkids']['child3']
thiskid['hair'] = 'blue'

割り当てによって辞書のhairキーが 変更されるため、パス全体を保存することはできません。 辞書を変更したい場合は、辞書に含まれているものではなく、辞書への参照が必要です。kidshair['allkids']['child3']

于 2012-04-29T11:34:02.490 に答える
1

現在のデータ構造で実行できる最も近い方法は、最後のdictを取得し、それを直接使用することです。

child = kidshair['allkids']['child3']

child['hair'] = 'blue'

これは、Pythonではスタイルの割り当てが原因です

name = value

新しいオブジェクトを「変数」にバインドするだけですname。これをオーバーロードする方法はなく、バインディングは他のオブジェクトに影響を与えることはできません(これまでこの名前にバインドされていたオブジェクトを解放することを除いて)。

一方、これは:

name[key] = value

name現在(あなたの場合はdict )にあるオブジェクトに対してアクション(アイテムを設定)を実行するため、まったく異なります。

于 2012-04-29T11:33:47.133 に答える
1

dpathlibhttps://pypi.org/project/dpath/を使用してみてください

>>> help(dpath.util.new)
Help on function new in module dpath.util:

new(obj, path, value)
Set the element at the terminus of path to value, and create
it if it does not exist (as opposed to 'set' that can only
change existing keys).

path will NOT be treated like a glob. If it has globbing
characters in it, they will become part of the resulting
keys

>>> dpath.util.new(x, 'a/b/e/f/g', "Roffle")
>>> print json.dumps(x, indent=4, sort_keys=True)
{
    "a": {
        "b": {
            "3": 2,
            "43": 30,
            "c": "Waffles",
            "d": "Waffles",
            "e": {
                "f": {
                    "g": "Roffle"
                }
            }
        }
    }
}
于 2019-10-31T08:36:44.213 に答える