Haryo Dollybim
Haryo Dollybim

Reputation: 99

How to arrange a list of tuples so that the tuple associated with the highest value compared to other tuple is removed and returns the maximum one

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.

Upvotes: 4

Views: 104

Answers (3)

timgeb
timgeb

Reputation: 78690

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])]

Upvotes: 1

iGian
iGian

Reputation: 11183

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])]

Upvotes: 1

Jean-François Fabre
Jean-François Fabre

Reputation: 140168

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())

Upvotes: 2

Related Questions