Hanson Johnson
Hanson Johnson

Reputation: 71

Returning the highest 6 names in a List of tuple in Python

Please I want to return first 6 names (only the names) with the highest corresponding integers from the list of tuple below. I have been able to return all the names from highest (sms) to lowest (boss).

[('sms', 10), ('bush', 9), ('michaels', 7), ('operations', 6), ('research', 5), ('code', 4), ('short', 3), ('ukandu', 2), ('technical', 1), ('apeh', 1), ('boss', 1)]

Thank you.

Upvotes: 7

Views: 870

Answers (3)

vartec
vartec

Reputation: 134631

data=[('sms', 10), ('bush', 9), ('michaels', 7), ('operations', 6), ('research', 5), ('code', 4), ('short', 3), ('ukandu', 2), ('technical', 1), ('apeh', 1), ('boss', 1)]
return [x[0] for x in sorted(data, key=lambda x: x[1], reverse=True)[0:6]]

Which does following:

  • sorted returns data sorted using key function. Since standard sorting order is from ascending, reverse=True sets it do descending;
  • lambda x: x[1] is anonymous function which returns second element of the argument (of a tuple in this case); itemgetter(1) is nicer way to do this, but requires additional imports;
  • [0:6] slices first 6 elements of the list;
  • [x[0] for x in ... ] creates a list of first elements of each passed tuple;

Upvotes: 4

mgilson
mgilson

Reputation: 310049

heapq.nlargest is what you want here:

import heapq
from operator import itemgetter
largest_names = [x[0] for x in heapq.nlargest(6,your_list,key=itemgetter(1))]

It will be more efficient than sorting as it only takes the biggest elements and discards the rest. Of course, it is less efficient than slicing if the list is pre-sorted for other reasons.

Complexity:

  • heapq: O(N)
  • sorting: O(NlogN)
  • slicing (only if pre-sorted): O(6)

Explanation:

heapq.nlargest(6,your_list,key=itemgetter(1)) 

This line returns a list of (name,value) tuples, but only the 6 biggest ones -- comparison is done by the second (index=1 --> key=itemgetter(1)) element in the tuple.

The rest of the line is a list-comprehension over the 6 biggest name,value tuples which only takes the name portion of the tuple and stores it in a list.


It might be of interest to you that you could store this data as a collections.Counter as well.

d = collections.Counter(dict(your_list))
biggest = [x[0] for x in d.most_common(6)]

It's probably not worth converting just to do this calculation (that's what heapq is for after all ;-), but it might be worth converting to make the data easier to work with.

Upvotes: 11

Sean Vieira
Sean Vieira

Reputation: 159995

If the data is already sorted simply slice off the first six tuples and then get the names:

first_six = data[0:6]  # or data[:6]
only_names = [entry[0] for entry in first_six]

The list comprehension can be unrolled to:

only_names = []
for entry in first_six:
    only_names.append(entry[0])

If the list is not already sorted you can use the key keyword argument of the sort method (or the sorted built-in) to sort by score:

data.sort(key=lambda entry: entry[1], reverse=True)

lambda is an anonymous function - the equivalent is:

def get_score(entry):
    return entry[1]

data.sort(key=get_score, reverse=True)

Upvotes: 1

Related Questions