2

I have a 2D list in python. I'd like to return the value of the first dimension where the sum of the second value is maximized. I don't care about breaking any ties and my first dimension will always be 1 through 6.

For example:

1)

list=[(1,200),(1,50),(2,275)]
should return 2 since 275 > 250

2)

list= [(1,100),(2,50),(2,300),(1,1000)
should return 1 since 1100 > 350

My attempted solution would work but be suboptimal (ideally id like a short 1-3 line solution) and uses the fact that my first dimension will only be the values 1-6. I'd like something a bit cleaner.

#for each element 1 through 6
For i in range(len(list)):
    if list[i][0]=1:
        #do this for oneSum, twoSum, etc, and take the largest sum
        oneSum+=list[i][1]
jfalkson
  • 3,471
  • 4
  • 20
  • 25
  • @XNor, that won't work. Notice that in the 2nd example, there were two tuples with the same first element and they had to be combined. – Oliver W. Mar 07 '15 at 23:38

2 Answers2

3

What about:

def foo(lst):
    d = {}
    for (k,v) in lst: d[k] = d.get(k,0) + v     # Accumulate
    return max(d.items(), key=lambda x:x[1])[0] # Find max value, return corresponding key

print foo([(1,200),(1,50),(2,275)])             # 2
print foo([(1,100),(2,50),(2,300),(1,1000)])    # 1

Or if you wanted the key and sum:

def foo(lst):
    d = {}
    for (k,v) in lst: d[k] = d.get(k,0) + v     # Accumulate
    return max(d.items(), key=lambda x: x[1])   # Find max value, return corresponding tuple

print foo([(1,200),(1,50),(2,275)])             # (2, 275)
print foo([(1,100),(2,50),(2,300),(1,1000)])    # (1, 1100)
jedwards
  • 29,432
  • 3
  • 65
  • 92
0

You can use Counter for this [a multiset, similar to defaultdict(int)] and many other problems

import collections

def max_key(items):
    counts = collections.Counter()
    for key, count in items:
        counts[key] += count
    return max(counts, key=lambda k: counts[k])

If your list of items is small and you want to be opaque code golf style, could do something like

  max((sum(x[0] for x in L), k) for k, L in itertools.groupby(sorted(list), lambda x: x[0]))[1]

Or other illegible variants, but please don't =(

Cireo
  • 4,197
  • 1
  • 19
  • 24