Вопрос по python – Перевести таблицу в иерархический словарь?

5

У меня есть таблица вида:

A1, B1, C1, (value)
A1, B1, C1, (value)
A1, B1, C2, (value)
A1, B2, C1, (value)
A1, B2, C1, (value)
A1, B2, C2, (value)
A1, B2, C2, (value)
A2, B1, C1, (value)
A2, B1, C1, (value)
A2, B1, C2, (value)
A2, B1, C2, (value)
A2, B2, C1, (value)
A2, B2, C1, (value)
A2, B2, C2, (value)
A2, B2, C2, (value)

Я хотел бы поработать с ним на python в качестве словаря в форме:

H = {
    'A1':{
        'B1':{
            'C1':[],'C2':[],'C3':[] },
        'B2':{
            'C1':[],'C2':[],'C3':[] },
        'B3':{
            'C1':[],'C2':[],'C3':[] }
    },
    'A2':{
        'B1':{
            'C1':[],'C2':[],'C3':[] },
        'B2':{
            'C1':[],'C2':[],'C3':[] },
        'B3':{
            'C1':[],'C2':[],'C3':[] }
    }
}

ЧтобыH[A][B][C] дает конкретный уникальный список значений. Для небольших словарей я мог бы просто заранее определить структуру, как указано выше, но я ищу эффективный способ перебора таблицы и построения словаря, без предварительного указания ключей словаря.

Вы всегда ищете тройку значений A, B, C? Если это так, вам будет лучше с однимdict используя эти тройки в качестве ключей. Fred Foo

Ваш Ответ

3   ответа
9
input = [('A1', 'B1', 'C1', 'Value'), (...)]

from collections import defaultdict

tree = defaultdict(lambda: defaultdict(lambda: defaultdict(list)))
#Alternatively you could use partial() rather than lambda:
#tree = defaultdict(partial(defaultdict, partial(defaultdict, list)))

for x, y, z, value in input:
    tree[x][y][z].append(value)
@ Lattyware Интересно, спасибо за это.
Обратите внимание, что если таблица представляет собой текстовый файл, вам понадобится что-то вродеwith open("table") as file: input = [line.split() for line in file].
Альтернативой использованию лямбд здесь является использованиеfunctools.partial(): tree = defaultdict(partial(defaultdict, partial(defaultdict, list))) - Я нахожу это понятнее, но это может быть только я.
Отлично, это работает именно так, как мне нужно. Спасибо! Chris Cox
2
d = {}
for (a, b, c, value) in your_table_of_tuples:
   d.setdefault(a, {}).setdefault(b,{}).setdefault(c,[]).append(value)
Зачем использоватьsetdefault() черезdefaultdict?
Вот почему я предложил свойfunctools.partial() Решение на основе в комментариях. ;) (Который может быть расширен для удобства чтения).
@ Lattyware: я бы сказал, что лямбды уродливы. де густибус ...
@ Lattyware: почему бы и нет?
Я бы сказал, что это намного ужаснее, когда вы его используете.
4

не используете только H [A] или H [A] [B]), я бы предложил более чистое решение IMO: используйте Tuples как defaultdict Index:

from collections import defaultdict
h = defaultdict(list)
for a, b, c, value in input:
    h[a, b, c].append(value)
Спасибо за размещение этого решения. В этом случае мне нужен доступ к словарям, но я не указал это в вопросе. Это будет чрезвычайно элегантно, если этот случай существует в будущем. Chris Cox
Это также очень правильное (и элегантное) решение, хотя оно требует, чтобы он не хотел получать доступ к поддиктам отдельно. (отредактировано для удаления некоторых дополнительных отступов, ненужных скобок и PEP-8, уточняющих имена переменных).

Похожие вопросы