简体   繁体   中英

Return the first key in Dictionary - Python 3

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

Shortest:

mydict = {"Key1" : "Value1", "Key2" : "Value2"}
print( next(iter(mydict)) ) # 'Key1'

For both the key and value:

print( next(iter( mydict.items() )) ) # ('Key1', 'Value1')

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

Edit:

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])

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

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 .

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 .

For Python 3 you can simply do

first_key = next(iter(data.keys()))
print(first_key)   # 'Key1'

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')

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM