web-dev-qa-db-ja.com

辞書で決定木を取得する

目的の構造に基づいて動的に辞書の辞書を作成する方法をpythonで探しています。

私は以下のデータを持っています:

{'weather': ['windy', 'calm'], 'season': ['summer', 'winter', 'spring', 'autumn'],  'lateness': ['ontime', 'delayed']} 

私は彼らになりたい構造を与えます:

['weather', 'season', 'lateness']

最後に、この形式でデータを取得します。

{'calm': {'autumn': {'delayed': 0, 'ontime': 0},
          'spring': {'delayed': 0, 'ontime': 0},
          'summer': {'delayed': 0, 'ontime': 0},
          'winter': {'delayed': 0, 'ontime': 0}},
 'windy': {'autumn': {'delayed': 0, 'ontime': 0},
           'spring': {'delayed': 0, 'ontime': 0},
           'summer': {'delayed': 0, 'ontime': 0},
           'winter': {'delayed': 0, 'ontime': 0}}}

これは私がこれを達成するために私が考えた手動の方法です:

dtree = {}
for cat1 in category_cases['weather']:
    dtree.setdefault(cat1, {})
    for cat2 in category_cases['season']:
        dtree[cat1].setdefault(cat2, {})
        for cat3 in category_cases['lateness']:
            dtree[cat1][cat2].setdefault(cat3, 0)

私が書いた構造を変更し、望ましい結果を得ることができる方法を考えられますか?構造が毎回同じサイズであるとは限らないことに注意してください。

また、私が結果にアクセスできる辞書以外の方法を考えれば、それも私にとってはうまくいきます。

5
bkbilly

以下は、r.ookが提供する優れた回答の解決策とは少し異なる再帰的な解決策です。

category_cases = {'weather': ['windy', 'calm'],
                  'season': ['summer', 'winter', 'spring', 'autumn'],
                  'lateness': ['ontime', 'delayed']}
order = ['weather', 'season', 'lateness']

def gen_tree(category_cases, order):
    if len(order) == 0:
        return 0
    return {x:gen_tree(category_cases, order[1:]) for x in category_cases[order[0]]}

notは、ディクショナリがキーの順序を保持すると想定しているため、より下位互換性があるはずです。

2
Nick Russo

はい、次のコードを使用してこれを実現できます。

import copy

structure = ['weather', 'season', 'lateness']
data = {'weather': ['windy', 'calm'], 'season': ['summer', 'winter', 'spring', 'autumn'],
        'lateness': ['ontime', 'delayed'], }

d_tree = dict()
n = len(structure)  # length of the structure list
prev_val = 0  # the innermost value
while n > 0:
    n -= 1
    keys = data.get(structure[n]) or list()  # get the list of values from data
    # Idea here is to start with inner most dict and keep moving outer
    d_tree.clear()
    for key in keys:
        d_tree[key] = copy.copy(prev_val)
    prev_val = copy.copy(d_tree)  # Copy the d_tree to put as value to outer dict
print(d_tree)

お役に立てれば!!

0
HNMN3