简体   繁体   中英

Python tuples dictionary addition

I have a dictionary of tuples as follows:

tupledict = {('A','B','C'):2, ('A',): 3, ('B',) :4, ('C',): 5}

Currently, the first tuple is 2, however I want it to read values from the individual tuples to give me the correct sum of 12.

So output should be:

tupledict = {('A','B','C'):12, ('A',): 3, ('B',) :4, ('C',): 5}

How could this be done?

You can use a dictionary comprehension to build a new dict:

>>> tupledict = {('A','B','C'): 2, ('A',): 3, ('B',): 4, ('C',): 5}
>>> {t: sum(tupledict.get((x,), 0) for x in t) for t in tupledict}
{('A', 'B', 'C'): 12, ('A',): 3, ('B',): 4, ('C',): 5}

Using tupledict.get() instead of indexing handles the case when some 1-tuple is missing.

You can do this as follows:

for key in list(tupledict):
    if len(key) > 1:
        tupledict[key] = sum(tupledict.get((subk,),0) for subk in key)

So we iterate over the list of keys (we use a list(..) such that we do not update a collection we are currently iterating over.

In case the len(key) is greater than 1, we calculate the sum of the subkeys, and assign that value to the tupledict .

This constructs the following dictionary:

>>> tupledict = {('A','B','C'):2, ('A',): 3, ('B',) :4, ('C',): 5}
>>> for key in list(tupledict):
...     if len(key) > 1:
...         tupledict[key] = sum(tupledict.get((subk,),0) for subk in key)
... 
>>> tupledict
{('A',): 3, ('B',): 4, ('C',): 5, ('A', 'B', 'C'): 12}

Alternatively, you can subclass the dictionary and override the __getitem__ such that if one requests a tuple with length greater than 1, it adds the elements together. In this case we will save on memory (and do not have to updated all tuples) since the tuples ('A','B','C') are stored implicitly :

class SumDict(dict):
    def __getitem__(self, key):
        if len(key) > 1:
            return sum(self.get((subk,) ,0) for subk in key)
        else:
            return super().__getitem__(key)

For example:

>>> tupledict = {('A',): 3, ('B',) :4, ('C',): 5}
>>> sd = SumDict(tupledict)
>>> sd[('A','B','C')]
12
>>> sd[('A','B')]
7

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM