Reputation:
I'm trying to print the key and value using the below code :
data = {"Key1" : "Value1", "Key2" : "Value2"}
print(data.keys()[1])
print(data.values()[1])
I get the error
'dict_keys' object does not support indexing
What is wrong with the mentioned code?
Accepted Output :
Key2
Value2
Upvotes: 11
Views: 47957
Reputation: 1669
For Python 3 you can simply do
first_key = next(iter(data.keys()))
print(first_key) # 'Key1'
Upvotes: 1
Reputation: 40038
Shortest:
mydict = {"Key1" : "Value1", "Key2" : "Value2"}
print( next(iter(mydict)) ) # 'Key1'
For both the key and value:
print( next(iter( mydict.items() )) ) # ('Key1', 'Value1')
Upvotes: 16
Reputation: 16952
It does rather depend on what you mean by first. In Python 3.6, entries in a dictionary are ordered by the key, but probably not quite in the way you expect.
To take your example:
>>> data = {"Key1" : "Value1", "Key2" : "Value2"}
Now add the key 0
:
>>> data[0] = "Value0"
>>> data
{'Key1': 'Value1', 'Key2': 'Value2', 0: 'Value0'}
So the zero comes at the end. But if you construct the dict from scratch, like this:
>>> data = {0: "Value0", "Key1" : "Value1", "Key2" : "Value2"}
you get this result instead
>>> data
{0: 'Value0', 'Key1': 'Value1', 'Key2': 'Value2'}
This illustrates the principle that you should not depend on the ordering, which is defined only by the dict implementation, which, in CPython 3.6 and later, is order of entry. To illustrate that point in a different way:
>>> data = {0: "Value0", "Key1" : "Value1", "Key2" : "Value2"}
>>> sorted(data.keys())
Traceback (most recent call last):
File "<pyshell#42>", line 1, in <module>
sorted(data.keys())
TypeError: '<' not supported between instances of 'str' and 'int'
Guido has this to say on the subject:
I'd like to handwave on the ordering of ... dicts. Yes, in CPython 3.6 and in PyPy they are all ordered, but it's an implementation detail. I don't want to force all other implementations to follow suit. I also don't want too many people start depending on this, since their code will break in 3.5. (Code that needs to depend on the ordering of keyword args or class attributes should be relatively uncommon; but people will start to depend on the ordering of all dicts all too easily. I want to remind them that they are taking a risk, and their code won't be backwards compatible.)
The full post is here.
Upvotes: 1
Reputation: 14689
in python3 data.keys()
returns a dict_keys
object, so, in general, apply list on it to be able to index/slice it:
data = {"Key1" : "Value1", "Key2" : "Value2"}
print(data.keys())
# output >>> dict_keys(['Key1', 'Key2'])
print(list(data.keys())[1])
# output >>> Key2
print(list(data.values())[1])
# output >>> Value2
For your specific case, you need to convert the dictionary to an ordered one to conserve the order and get the first element as follows:
from collections import OrderedDict
data = {"Key1" : "Value1", "Key2" : "Value2"}
data = OrderedDict(data)
print(data)
# output >>> OrderedDict([('Key1', 'Value1'), ('Key2', 'Value2')])
print(list(data.keys())[0])
# output >>> Key1
Based on comments from @Mseifert (thanks), preserving the order after conversion from the unordered dictionary to the ordered one is only an implementation detail that works in python3.6 and we cannot rely on, here's the discussion Mseifert shared:
So the correct way to do what you want is to explicitly define the order
from collections import OrderedDict
data = OrderedDict([('Key1', 'Value1'), ('Key2', 'Value2')])
print(list(data.keys())[0])
Upvotes: 14
Reputation: 3956
Dicts represent an unordered datatype, therefore there is no indexing. There is an option in collections. Try OrderedDict.
import collections
d = collections.OrderedDict()
d['Key1'] = 'Value1'
d['Key2'] = 'Value2' # that's how to add values to OrderedDict
items = list(d.items())
print(items)
#[('Key1', 'Value1'), ('Key2', 'Value2')]
print(items[0])
#('Key1', 'Value1')
print(items[1])
#('Key2', 'Value2')
Upvotes: 0
Reputation: 152657
Dictionaries are unordered and in the newer Python versions the hashes of strings are randomized (per session). So you have to accept that what you get as "n"-th key (or value) of a dictionary isn't predictable (at least when the keys are strings).
But if you just want the element that happens to be "first" (or "second") just use list
to convert the dict_keys
to an sequence that can be indexed:
print(list(data.keys())[1])
print(list(data.values())[1])
However, my suggestion would be to use an OrderedDict
instead of a normal dict to make the result deterministic:
from collections import OrderedDict
data = OrderedDict([("Key1", "Value1"), ("Key2", "Value2")])
print(list(data.keys())[1]) # Key2
print(list(data.values())[1]) # Value2
Upvotes: 3
Reputation: 3361
In Python, dict
s are unordered data structures. Therefore there is no first key. If you want to have a dict
-like data structure with internal ordering of keys, have a look at OrderedDict
.
Upvotes: 1