Переформировать словарь ключей - PullRequest
1 голос
/ 21 мая 2019

У меня есть словарь с двумерными ключами:

{('a', 'b'): 2, ('a', 'd'): 3, ('b', 'e'): 4, (' b ',' f '): 5}.

Хотите создать вложенный словарь, например

{' a ': {' b ': 2,'d': 3}, 'b': {'e': 4, 'f': 5}

Есть ли разумный способ сделать это (вместо использования цикла)?

Ответы [ 2 ]

2 голосов
/ 21 мая 2019

Использование цикла и defaultdict

Я не уверен, что вы можете сделать это без цикла, но вы можете использовать defaultdict и распаковать все ключи и значения:

from collections import defaultdict

d = defaultdict(dict)

something = {('a','b'):2,('a','d'):3,('b','e'):4,('b','f'):5}

for (k, k1), v in something.items():
    d[k][k1] = v

print(d)
defaultdict(<class 'dict'>, {'a': {'b': 2, 'd': 3}, 'b': {'e': 4, 'f': 5}})

Понимание Dict и groupby itertools

Кроме того, вы можете использовать понимание DICT по результатам itertools.groupby

from itertools import groupby

something = {('a','b'):2,('a','d'):3,('b','e'):4,('b','f'):5}

d = dict((i, {k1: v for (k, k1), v in x}) for i,x in groupby(something.items(), key = lambda x: x[0][0]))

{'a': {'b': 2, 'd': 3}, 'b': {'e': 4, 'f': 5}}

Где keyfunc группируется по тому, что k в собственном цикле defaultdict

Сроки

defaultdict

python -m timeit -s 'import defaultdictloop as lp; something=lp.something' 'lp.defaultdict_loop(something)'
1000000 loops, best of 3: 0.557 usec per loop

itertools

python -m timeit -s 'import defaultdictloop as lp; something=lp.something' 'lp.itertools_loop(something)'
100000 loops, best of 3: 2.56 usec per loop
1 голос
/ 22 мая 2019

Вот решение, использующее списочные выражения и itertools.groupby вместо явных циклов.

import itertools as it

d={('a','b'):2,('a','d'):3,('b','e'):4,('b','f'):5}

d_items=[[k[0],k[1],v] for k,v in d.items()]

d_items=sorted(d_items, key=lambda x: x[0])

new_d=dict((k,dict(tuple(v))) for k,v in it.groupby(d_items,lambda x: x.pop(0)))

print(new_d)

{'a': {'b': 2, 'd': 3}, 'b': {'e': 4, 'f': 5}}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...