Python dictionary.keys() error
Python 3 changed the behavior of dict.keys
such that it now returns a dict_keys
object, which is iterable but not indexable (it's like the old dict.iterkeys
, which is gone now). You can get the Python 2 result back with an explicit call to list
:
>>> b = { 'video':0, 'music':23 }>>> k = list(b.keys())>>> k['music', 'video']
or just
>>> list(b)['music', 'video']
If you assigned k
like so:
k = list(b.keys())
your code will work.
As the error says, the dict_keys
type does not support indexing.
This is one of the breaking changes between Python 2 and 3.
In Python 2:
>>> help(dict.keys)keys(...) D.keys() -> list of D's keys
In Python 3:
>>> help(dict.keys)keys(...) D.keys() -> a set-like object providing a view on D's keys
This change in behavior makes a lot of sense since a dict is semantically unordered and its keys are unique - just like a set.
This change means that you don't have to create a new list of keys every time you want to do some kind of set comparison with a dict's keys.
Getting the same behavior in 2 and 3
To help transition to Python 3, Python 2.7 has another dict method, viewkeys
. The viewkeys
method is most similar to Python 3's dict.keys
method:
>>> d{'a': None, 'c': None, 'b': None, 'd': None}>>> for k in d.viewkeys(): print k... acbd>>> d.viewkeys() & set('abc')set(['a', 'c', 'b'])
In Python 3, the closest analog to the old behavior is to pass dict.keys()
to list
:
>>> d{'d': None, 'a': None, 'c': None, 'b': None}>>> list(d.keys())['d', 'a', 'c', 'b']
Or just pass the dict to list
, since a dict will iterate over its keys anyways:
>>> list(d)['d', 'a', 'c', 'b']
You could create a utility functions to abstract the behavior over 2 and 3:
if hasattr(dict, 'viewkeys'): # Python 2.7 def keys(d): return d.viewkeys()else: # Python 3 def keys(d): return d.keys()
And pass a dict to list
to get the list form, and in both 2 and 3, you'll get the same output:
>>> d{'b': None, 'a': None, 'c': None, 'd': None}>>> keys(d)dict_keys(['b', 'a', 'c', 'd'])>>> list(d)['b', 'a', 'c', 'd']