4
val = [(200, []), (300, [500, 200]), (400, [100, 200, 300]), (400, [])]
largest_val_arrangement(val)
[(200, []), (300, [500, 200]), (400, [100, 200, 300])]

so now (400, []) is poped out because (400, [100, 200, 300]) has more elements than it.

Liam
  • 6,009
  • 4
  • 39
  • 53

3 Answers3

2

you could use sort according to the length of the list, and use a dictionary so the last written key "wins".

Then convert back to tuple or list or ... leave as dict:

val = [(200, []), (300, [500, 200]), (400, [100, 200, 300]), (400, [])]

def largest_val_arrangement(val):
    return tuple({k:v for k,v in sorted(val, key = lambda t : len(t[1]))}.items())

largest_val_arrangement(val)

result:

((200, []), (400, [100, 200, 300]), (300, [500, 200]))

This method, like the sort it uses, has O(log(n)*n) complexity, (dict has O(1) average complexity).

But one-liners aren't always the most efficient solutions. Here using sort is unnecessary, when a good old loop with a marker dict works in O(n):

def largest_val_arrangement(val):
    d = dict()
    for k,v in val:
        if k not in d or len(d[k]) < len(v):
            d[k] = v

    return tuple(d.items())
Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
1

O(n) solution

>>> val = val = [(200, []), (300, [500, 200]), (400, [100, 200, 300]), (400, [])]
>>>
>>> seen = {}
>>> for k, lst in val:
...:    if len(lst) > len(seen.get(k, [])):
...:        seen[k] = lst
...:        
>>> list(seen.items())
[(200, []), (300, [500, 200]), (400, [100, 200, 300])]
timgeb
  • 76,762
  • 20
  • 123
  • 145
1

Other option, using a default dictionary from collections:

val = [(200, []), (300, [500, 200]), (400, [100, 200, 300]), (400, [])]

from collections import defaultdict
tmp = defaultdict(list)

for x in val:
  if len(x[1]) > len(tmp[x[0]]): tmp[x[0]] = x[1]

res = [(k, v) for k,v in tmp.items()]
print(res)

#=> [(200, []), (300, [500, 200]), (400, [100, 200, 300])]
iGian
  • 11,023
  • 3
  • 21
  • 36