buggsbunny4
buggsbunny4

Reputation: 181

Get Maximum Value based upon Multiple Dictionary Objects using Python

I have a dictionary item from which I would like to get the maximum value. This dictionary consists of 2 dictionaries. The following is the dictionary

new_f_key: {'previous_f_key': {'1g': ['33725.7', '-70.29'],
                               '2g': ['35613.3', '108.83'],
                               '3g': ['32080.9', '-69.86']},
            'f_key': {'1g': ['8880.8', '-66.99'],
                      '2g': ['6942.6', '114.79'],
                      '3g': ['12300.3', '-70.34']}}

I was trying to use the above iteritems() and itemgetter() but I am not getting the value I wanted.

It should compare all values from the two dictionaries and output the value which is highest and also output the header of that item along with the dictionary in which it exists.

For example, in the above dictionary, the maximum value is 35613.3 and the key for that is 2g and it occurred in first dictionary object which is previous_f_key.

Upvotes: 1

Views: 1691

Answers (4)

inspectorG4dget
inspectorG4dget

Reputation: 113935

Check this out:

def maxVal(d):
    if all(isinstance(v, list) for v in d.values()):
        return max(d, key=lambda k: max(d[k]))
    else:
        k = max(d, key=lambda k: maxVal(d[k]))
        return k + ":" + maxVal(d[k])

Testing:

In [79]: %paste
    def maxVal(d):
        if all(isinstance(v, list) for v in d.values()):
            return max(d, key=lambda k: max(d[k]))
        else:
            k = max(d, key=lambda k: maxVal(d[k]))
            return k + ":" + maxVal(d[k])

## -- End pasted text --

In [80]: %paste
dic = {'previous_f_key': {'1g': ['33725.7', '-70.29'],
                               '2g': ['35613.3', '108.83'],
                               '3g': ['32080.9', '-69.86']},
            'f_key': {'1g': ['8880.8', '-66.99'],
                      '2g': ['6942.6', '114.79'],
                      '3g': ['12300.3', '-70.34']}}

## -- End pasted text --

In [81]: maxVal(dic)
Out[81]: 'previous_f_key:2g'

Upvotes: 1

Marcin
Marcin

Reputation: 49826

Do this. It will handle arbitrary nesting, and it's short.

def weird_max(d, key=float):
    vals = []
    for item in d.itervalues():
        if isinstance(item, dict):
            vals.append(weird_max(item))
        else: # should be a list
            vals.extend(item)
    return max(vals, key=key)

That said, it relies on type tests, which is less than elegant. I'd generally recommend that you don't do this sort of thing, and either keep a running track of the maximum value, or find a better datastructure to represent this information, e.g. a heap.

ideone here: http://ideone.com/rJ1YZh

Upvotes: 1

Ashwini Chaudhary
Ashwini Chaudhary

Reputation: 250931

dic = {'previous_f_key': {'1g': ['33725.7', '-70.29'],
                               '2g': ['35613.3', '108.83'],
                               '3g': ['32080.9', '-69.86']},
            'f_key': {'1g': ['8880.8', '-66.99'],
                      '2g': ['6942.6', '114.79'],
                      '3g': ['12300.3', '-70.34']}}

maxx = float('-inf')
for d,v in dic.iteritems():
    for k,v1 in v.iteritems():
        loc_max = float(max(v1, key = float))
        if loc_max > maxx:
            outer_key = d
            header = k
            maxx = loc_max

print outer_key, header, maxx

Output:

previous_f_key 2g 35613.3

Upvotes: 1

sedavidw
sedavidw

Reputation: 11691

You'll need to create a nested loop:

max = -1
maxkey = -1
maxdic = -1
for dic_name, dic in new_f_key.iteritems():
     for key, val in dic.iteritems():
          if val > max:
              max = val
              maxkey = key
              maxdic = dic_name

You can probably save the reference to the dictionary as a simple integer flag, I just did this here for clarity

Upvotes: 0

Related Questions