emihir0
emihir0

Reputation: 1250

Nested dictionary sum all values

I have a seemingly easy problem, but can't solve it.

Dictionary = {
    'own': {
        'Dun Morogh': {
            'Horde': {
                'chars': {
                    'Qiidu': {
                        'auction': 1
                        }
                    }
                 }
            }, 
        'Tirion': {
            'Alliance': {
                'chars': {
                    'Qiip': {
                        'auction': 1
                         }
                     }
                 }
            }, 
        'Proudmoore': {
            'Alliance': {
                'chars': {
                    'Qiip': {
                        'mail': 1
                        }
                    }
                }
            } 
        }, 
    'name': u'Rascal-Bot'
}

This is the format I have my dictionary in and I want to loop through it, sum all the integers in it and return it.

My code:

def findTotal(self, dct):
    for key, value in dct.iteritems():
        if isinstance(value, int):
            print key, value
        if isinstance(value, dict):
            self.findTotal(value)

This works on 'printing', but how would I adjust it to 'summing up'?

Upvotes: 1

Views: 1438

Answers (3)

Drlight Dr
Drlight Dr

Reputation: 9

recursive even sum

def traverse(dic):
    if dic == {}:
        return 0
    elif isinstance(dic[list(dic)[0]], int) and dic[list(dic)[0]] % 2 == 0:
        return 1 + traverse({i: dic[i] for i in list(dic)[1:]})
    elif isinstance(dic[list(dic)[0]], int) and dic[list(dic)[0]] % 2 != 0:
        return 0 + traverse({i: dic[i] for i in list(dic)[1:]})
    return traverse(dic[list(dic)[0]]) + traverse({i: dic[i] for i in list(dic)[1:]})

Upvotes: 0

AChampion
AChampion

Reputation: 30268

Given you are using a recursive function you need to return the sum up the call stack:

def findTotal(self, dct):
    total = 0
    for key, value in dct.iteritems():
        if isinstance(value, int):
            total += value
        if isinstance(value, dict):
            total += self.findTotal(value)
    return total

Alternately you could recurse into each option and check for a terminal case:

def findTotal(self, item):
    if isintance(item, int):
        return item
    if not isintance(item, dict):
        return 0

    total = 0
    for value in item.itervalues():
        total += self.findTotal(value)
    return total

Upvotes: 0

Blorgbeard
Blorgbeard

Reputation: 103467

You can add a sum variable to keep track of the sum, and have your function return that value. The recursive calls will add up the "sub-sums" and return them to their callers, who will add them to their totals, until you're back to the first call, and the grand total.

def findTotal(self, dct):
    total = 0
    for key, value in dct.iteritems():
        if isinstance(value, int):
            total += value
        if isinstance(value, dict):
            total += self.findTotal(value)
    return total

Upvotes: 4

Related Questions