Summing a tuple-of-tuples and a nested dict

扶醉桌前 提交于 2020-01-06 03:03:09

问题


I have data that can be represented in two different forms (for historical reasons that I won't go into). The first is a tuple of tuples:

t = (('a', 'x', 3), 
('a', 'f', 1), 
('b', 'r', 23), 
('b', 'e', 3))

And the second as a dict of dicts:

d = {'a' : {'x': 45, 'f' : 4},
     'b' : {'r' : 34, 'e' : 45}}

Same data, different representation. I now need to end up with a combination of the two (and must maintain the tuple-of-tuples form rather than the nested dict form), with the values summed. i.e.

(('a', 'x', 48), 
('a', 'f', 5), 
('b', 'r', 57), 
('b', 'e', 48))

It seems this is a two-step process (convert the nested dict to a tuple of tuples, then sum the corresponding tuples within each tuple). I'm struggling to get past the first part, I am missing two tuples (and I don't like how I have hardcoded the indexing either):

In [1025]: def f(d):
    for k, v in d.items():
        yield (k, d[k].keys()[0], d[k].values()[0])
   ......:         

In [1026]: for i in f(d):

    print i
   ......:     
('a', 'x', 45)
('b', 'r', 34)

What is a better way?


回答1:


You can use a generator expression within tuple(), by looping over your tuples and summing the third item with it's relative value in dictionary:

>>> tuple((i, j, k + d.get(i, {}).get(j, 0)) for i, j, k in t)
(('a', 'x', 48),
 ('a', 'f', 5),
 ('b', 'r', 57),
 ('b', 'e', 48))

Note that the advantage of using dict.get() method is that it returns 0 if the key doesn't exist in dictionary.

Note that if it doesn't make any difference for you to have a list of tuples or tuple of tuples, you can use a list comprehension instead of a generator expression. because list comprehension is more optimized in terms of runtime as it doesn't need to call extra methods like next() in a generator function in order to retrieve the items.




回答2:


You can use a list comprehension converted to a tuple provided you are sure that all your tuple and dicts contain exactly same elements (it works with current example):

tuple([(x, y, z + d[x][y]) for x, y, z in t ])

correctly gives:

(('a', 'x', 48), ('a', 'f', 5), ('b', 'r', 57), ('b', 'e', 48))


来源:https://stackoverflow.com/questions/37341822/summing-a-tuple-of-tuples-and-a-nested-dict

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!