0

If i have a dictionary that has two values per entry in a tuple eg . (jon, 100) (ellie, 200) (mati, 120) (steve, 250) I want to order them in order of their score (second value). But then i only want to display the names. eg : steve, ellie, mati , jon how would i go about it?

f = open('data.csv','r')
reader = csv.reader(f)
new_dict = {}

for row in reader:
    new_dict[row[0]] = random.gauss(float(row[1]), float(row[2]))

order_list = sorted(new_dict, key = new_dict[row[0]], reverse = False)
return order_list

so far i got this and i also get errors like

"order_list = sorted(new_dict, key = new_dict[row[0]], reverse = False)"

TypeError: 'float' object is not callable

any help would be grand.

Struggler
  • 3
  • 1

3 Answers3

0

First sort the values with a key function that gets the score only, and then get the first item of the pairs from the sorted data.

from operator import itemgetter
order_list = [e[0] for e in sorted(new_dict.values(), key=itemgetter(1), reverse=True)]

The reverse=True is because you wanted the highest-scoring name first, so it's a descending sort instead of the default ascending.

That itemgetter(1) function is equivalent to lambda e: e[1], which would also work.

order_list = [e[0] for e in sorted(new_dict.values(), key=lambda e: e[1], reverse=True)]

If itemgetter(1) seems like a long-winded way to make a simple lambda, note that you could have instead used from operator import itemgetter as ig and then written key=ig(1)

gilch
  • 10,813
  • 1
  • 23
  • 28
  • Return a callable object that fetches item from its operand using the operand’s __getitem__() method. If multiple items are specified, returns a tuple of lookup values. – Struggler Dec 13 '18 at 03:07
  • Note also that `e[1]` is equivalent to `e.__getitem__(1)`. – gilch Dec 13 '18 at 03:08
0
>>> d = {'ellie': 200, 'jon': 100, 'mati': 120, 'steve': 250}
>>> sorted(d, key=lambda k: d[k])
['jon', 'mati', 'ellie', 'steve']

sorted treats the dictionary as an iterator, and retrieves the keys of the dictionary.

The key parameter must be a function (in this case an unnamed function, a lambda) that returns a sorting key for the current value being sorted.

jnnnnn
  • 3,889
  • 32
  • 37
  • That's not the data structure described though. Where's the "two values per entry in a tuple"? – gilch Dec 13 '18 at 03:16
0

This is the solution.

    import pandas as pd

    def names_ordered_by_score(file_name):
        df = pd.read_csv(file_name, names=['name', 'score'])
        df.sort_values(by='score', inplace=True)
        return df.name.values.tolist()

    names_ordered_by_score('data.csv')

This is a hard-coded test.

    import pandas as pd

    def names_ordered_by_score():
        df = pd.DataFrame([('jon', 100), 
                           ('ellie', 200), 
                           ('mati', 120)], 
                          columns=['name', 'score'])
        df.sort_values(by='score', inplace=True)
        return df.name.values.tolist()

    names_ordered_by_score()
Indominus
  • 1,228
  • 15
  • 31
  • The OP didn't indicate that they're using Pandas. This is a rather heavy library to import for this task. – souldeux Dec 13 '18 at 03:28
  • 1
    I think you're over-complicating it. This can be done in one line. A beginner shouldn't start using heavyweight data processing libraries like pandas before understanding the batteries-included basics. – gilch Dec 13 '18 at 03:29