8

I'm new to python, and am trying to write code, using a dictionary, that can determine the order of the winners of a race. (Basically a sort of the keys using the values of the dictionary). The following is my code:

runners = {

    str(input("Please put in name 1")):input("Please put in a number 1"),
    str(input("Please put in name 2")):input("Please put in a number 2"),
    str(input("Please put in name 3")):input("Please put in a number 3"),
}

def find_winner_name(dictionary):
  winner_score = min(dictionary.values())
  for i in dictionary.keys():
    if winner_score == dictionary[dictionary.keys()[i]]:
      return dictionary.keys()[i]

winnerName = find_winner_name(runners)
print(winnerName)#simply to make sure this is working so far

The following is the error message:

TypeError: 'dict_keys' object is not subscriptable

can somebody explain what I'm doing wrong to me? As far as I know, dictionary.keys() should return a list of keys, which should be subscriptable.

Ploni
  • 111
  • 1
  • 1
  • 8
  • 5
    You are on Python 3, so `dictionary.keys()` returns *a view*, not a list. And that is a *very good thing*. – juanpa.arrivillaga Jul 20 '17 at 17:39
  • Anyway, there is absolutely *no need to index into your keys*. Just do `for k in my_dict: do_stuff(my_dict[k])` – juanpa.arrivillaga Jul 20 '17 at 17:40
  • Thank you for your comment, this is my first day using ptyhon, and i forgot that this for loop acts like a for-each loop. Meaning that i wasnt an index, its the reference to each element. I simply changed all of the dictionary[i] to i and my code works. – Ploni Jul 20 '17 at 17:46
  • 4
    A much more elegant way: `for key, value in dictionary.items(): if value == winnerscore: return key` – juanpa.arrivillaga Jul 20 '17 at 17:50
  • Although note, dictionaries are unordered, so you are returning the first key to have that value, and that will be in an arbitrary, although deterministic, order. – juanpa.arrivillaga Jul 20 '17 at 17:51
  • when I realized my mistake I changed it to exactly what you just wrote. And yes, I do realize that. I wrote this code simply to help me learn syntax – Ploni Jul 20 '17 at 17:58
  • 2
    If you want to simply port your python2 script and convert it to python3, you can change `dictionary.keys()` to `list(dictionary)`. The way to extract keys from a python 3 dictionary is using the `list()` command. *But don't do that.* Use the pythonic methods as mentioned in the comments where you loop over the items in a `key,value` pair. – Mark Lakata Nov 26 '19 at 20:17
  • 1
    @juanpa.arrivillaga Would you mind explaining why it's a very good thing that dictionary.keys() returns a view and not a list? – Somatic Custard Feb 18 '20 at 15:51
  • 2
    @SomaticCustard because then `dictionary.keys()` is a constant time / space operation. When it returned a list, as it used to in Python 2, it would take linear time and space. Also, the view is set-like and supports set operations. – juanpa.arrivillaga Feb 18 '20 at 18:14
  • @juanpa.arrivillaga, if the view is set-like, wouldn't it support .pop()? – dangel Nov 28 '21 at 02:23
  • 1
    @dangel no. It supports most set operations, union, intersection... it implements the abstract `collections.abc.Set` interface, see [here](https://docs.python.org/3/library/collections.abc.html), note, it doesn't implement `MutableSet` – juanpa.arrivillaga Nov 28 '21 at 02:45

0 Answers0