8

私は以下のリストを持っています -

keyList1 = ["Person", "Male", "Boy", "Student", "id_123", "Name"]
value1 = "Roger"

以下のように取得できる動的辞書を生成するにはどうすればよいですか -

mydict["Person"]["Male"]["Boy"]["Student"]["id_123"]["Name"] = value

リストは何でもかまいません。可変長または「N」個の未知の要素で構成される...

今、私は別のリストを持っているので、それに応じて私の辞書を更新する必要があります

keyList2 = ["Person", "Male", "Boy", "Student", "id_123", "Age"]
value2 = 25

つまり、キー "Person"、"Male"、"Boy"、"Student"、"id_123" が既に存在する場合は、新しいキー "age" を追加する必要があります ...

4

7 に答える 7

8

私はPythonを学んでいるので、私のコードはあまりPythonicではないかもしれませんが、これが私のコードです

d = {}

keyList1 = ["Person", "Male", "Boy", "Student", "id_123", "Name"]
keyList2 = ["Person", "Male", "Boy", "Student", "id_123", "Age"]
value1 = "Roger"
value2 = 3

def insert(cur, list, value):
    if len(list) == 1:
        cur[list[0]] = value
        return
    if not cur.has_key(list[0]):
        cur[list[0]] = {}
    insert(cur[list[0]], list[1:], value)

insert(d, keyList1, value1)
insert(d, keyList2, value2)

{'Person': {'Male': {'Boy': {'Student': {'id_123': {'Age': 3, 'Name': 'Roger'}}}}}}
于 2013-07-04T04:55:32.910 に答える
4

これを行うには、ネストされたdefaultdicts を作成します。

from collections import defaultdict

def recursive_defaultdict():
    return defaultdict(recursive_defaultdict)

def setpath(d, p, k):
    if len(p) == 1:
        d[p[0]] = k
    else:
        setpath(d[p[0]], p[1:], k)

mydict = recursive_defaultdict()

setpath(mydict, ["Person", "Male", "Boy", "Student", "id_123", "Name"], 'Roger')

print mydict["Person"]["Male"]["Boy"]["Student"]["id_123"]["Name"]
# prints 'Roger'

これには、書き込みができるという優れた利点があります。

mydict['a']['b'] = 4

setpath必ずしもヘルパーを使用する必要はありません。

再帰的なdefaultdictsなしでも実行できます。

def setpath(d, p, k):
    if len(p) == 1:
        d[p[0]] = k
    else:
        setpath(d.setdefault(p[0], {}), p[1:], k)
于 2013-07-04T05:18:47.390 に答える
1

initメソッドがリストと単一の値を入力として取り、キーを値に設定してリストを反復処理するdict から派生した独自のクラスを作成し、リストと新しい値を受け取る更新メソッドを定義します。すでにキーが新しい値に設定されています(それが必要なものであると仮定します)。

という考えを忘れて

mydict["人物"]["男性"]["男の子"]["学生"]["id_123"]["名前"] = value1`

サブインデックスと紛らわしいからです。

于 2013-07-04T05:09:58.813 に答える
0

キーとして使用tuple(keyList1)します。(タプルは不変であるため、dict キーにすることができます)。

ネストされた dict アプローチでは頭痛の種になります。(列挙のためのネストされたループ、階層を変更する必要がある場合のレガシー データなど)。

考え直して、おそらく person クラスを定義する必要があります

class Person(object):
    gender = "Male"
    group = "Student"
    id = 123
    Name = "John Doe"

次に、すべての人のリストを使用して、たとえば次のようにフィルタリングします

male_students = [s for s in  ALL_PERSONS where s.gender=="Male" and s.group="Student"]

... <= 10000 人の学生の場合、パフォーマンスは問題ないはずです。

于 2013-07-04T05:35:37.140 に答える
0

私は同様のものを扱おうとしているので、いくつかのガイドラインを提案できますが、やはり私は Python に慣れていないので、これは単なるガイドラインです...

キーのリストがあるので、値ごとにループを繰り返すことから始めて、値を割り当てることができます

お気に入り

for i in keylist:
if type(keylist[i]) == dict:
        do something
    else:
        keylist[i] = {}

何かを行うには、i をインクリメントしてインデックスを [i][i+1] に変更し、i+n = len(keylist) まで同じ手順に従う必要があります。

于 2013-07-04T05:20:28.560 に答える
-2
>>> mydict = {}
>>> keyList1 = ["Person", "Male", "Boy", "Student", "id_123", "Name"]
>>> value1 = "Roger"
>>> reduce(lambda x, y: x.setdefault(y, {}), keyList1, mydict)
{}
>>> mydict["Person"]["Male"]["Boy"]["Student"]["id_123"]["Name"] = value1

このようにワンステップで行うこともできます

>>> keyList2 = ["Person", "Male", "Boy", "Student", "id_123", "Age"]
>>> value2 = 25
>>> reduce(lambda x,y: x.setdefault(y,{}), keyList2[:-1], mydict).update({keyList2[-1]: value2})
于 2013-07-04T04:54:32.507 に答える