135

Consider a dict like

mydict = {
  'Apple': {'American':'16', 'Mexican':10, 'Chinese':5},
  'Grapes':{'Arabian':'25','Indian':'20'} }

How do I access for instance a particular element of this dictionary? for instance, I would like to print the first element after some formatting the first element of Apple which in our case is 'American' only?

Additional information The above data structure was created by parsing an input file in a python function. Once created however it remains the same for that run.

I am using this data structure in my function.

So if the file changes, the next time this application is run the contents of the file are different and hence the contents of this data structure will be different but the format would be the same. So you see I in my function I don't know that the first element in Apple is 'American' or anything else so I can't directly use 'American' as a key.

simhumileco
  • 31,877
  • 16
  • 137
  • 115
alessandra
  • 1,359
  • 2
  • 9
  • 4
  • 2
    Can you please give an example of the output you expect? – Björn Pollex Mar 23 '11 at 11:50
  • 3
    What do you actually want to do with this structure? And do you know the keys of the dict ('Apple' and 'Grapes' in your example)? Or do you only know that you will get a dict of dicts? – juanchopanza Mar 23 '11 at 15:50
  • Note: This question is about accessing dict elements by *index*, which makes no sense because dicts are unordered. For a question about accessing elements in a nested dict, see [Python - accessing values nested within dictionaries](//stackoverflow.com/q/11700798). – Aran-Fey Oct 09 '18 at 12:03
  • @Aran-Fey: unordered things have an intrinsic order. Unordered != no order. – Jamie Marshall Mar 22 '19 at 15:44

12 Answers12

140

Given that it is a dictionary you access it by using the keys. Getting the dictionary stored under "Apple", do the following:

>>> mydict["Apple"]
{'American': '16', 'Mexican': 10, 'Chinese': 5}

And getting how many of them are American (16), do like this:

>>> mydict["Apple"]["American"]
'16'
Morten Kristensen
  • 7,412
  • 4
  • 32
  • 52
  • 11
    How could one do this dynamically without knowing the depth of the elements? – Ethan Bierlein May 10 '15 at 02:57
  • 3
    What exactly would you like to know? You can get the keys of a dictionary with `.keys()` so you can access them dynamically. – Morten Kristensen May 13 '15 at 11:40
  • 3
    Like, for example, if you had a dictionary of unknown depth, e.g, a nested dictionary, and you have element `"n"` at an unknown depth, stored in an unknown element. – Ethan Bierlein May 13 '15 at 12:27
  • 1
    That's a very broad question. Given your data structure you would then write a function or class to handle it appropriately. Perhaps you could supply a key and a strategy for trying to find the key. – Morten Kristensen May 14 '15 at 08:10
  • 1
    @EthanBierlein use: 'for key,value in dictionary.iteritems()' to have access to both key and value – danius Oct 27 '15 at 09:57
  • 1
    If you would only know how many hours I've spent trying to isolate a specific value from a dictionary.. only to finally stumble upon your answer- and for that I heartily thank you. – soBusted Aug 07 '19 at 20:29
25

If the questions is, if I know that I have a dict of dicts that contains 'Apple' as a fruit and 'American' as a type of apple, I would use:

myDict = {'Apple': {'American':'16', 'Mexican':10, 'Chinese':5},
          'Grapes':{'Arabian':'25','Indian':'20'} }


print myDict['Apple']['American']

as others suggested. If instead the questions is, you don't know whether 'Apple' as a fruit and 'American' as a type of 'Apple' exist when you read an arbitrary file into your dict of dict data structure, you could do something like:

print [ftype['American'] for f,ftype in myDict.iteritems() if f == 'Apple' and 'American' in ftype]

or better yet so you don't unnecessarily iterate over the entire dict of dicts if you know that only Apple has the type American:

if 'Apple' in myDict:
    if 'American' in myDict['Apple']:
        print myDict['Apple']['American']

In all of these cases it doesn't matter what order the dictionaries actually store the entries. If you are really concerned about the order, then you might consider using an OrderedDict:

http://docs.python.org/dev/library/collections.html#collections.OrderedDict

JoshAdel
  • 66,734
  • 27
  • 141
  • 140
22

As I noticed your description, you just know that your parser will give you a dictionary that its values are dictionary too like this:

sampleDict = {
              "key1": {"key10": "value10", "key11": "value11"},
              "key2": {"key20": "value20", "key21": "value21"}
              }

So you have to iterate over your parent dictionary. If you want to print out or access all first dictionary keys in sampleDict.values() list, you may use something like this:

for key, value in sampleDict.items():
    print value.keys()[0]

If you want to just access first key of the first item in sampleDict.values(), this may be useful:

print sampleDict.values()[0].keys()[0]

If you use the example you gave in the question, I mean:

sampleDict = {
              'Apple': {'American':'16', 'Mexican':10, 'Chinese':5},
              'Grapes':{'Arabian':'25','Indian':'20'}
              }

The output for the first code is:

American
Indian

And the output for the second code is:

American

EDIT 1:

Above code examples does not work for version 3 and above of python; since from version 3, python changed the type of output of methods keys and values from list to dict_values. Type dict_values is not accepting indexing, but it is iterable. So you need to change above codes as below:

First One:

for key, value in sampleDict.items():
    print(list(value.keys())[0])

Second One:

print(list(list(sampleDict.values())[0].keys())[0])
Zeinab Abbasimazar
  • 9,835
  • 23
  • 82
  • 131
  • not working for me, I get " 'dict_values' object is not subscriptable ". I am using python 3.7. – Angelo Sajeva Oct 23 '20 at 09:08
  • @AngeloSajeva, you are right. It's because version 3 of python changed the output type of methods `values` and `keys` of dictionaries from `list` to `dict_values`. You may need to cast them to list before accessing them using index. I edited my answer with more details. – Zeinab Abbasimazar Oct 25 '20 at 17:37
10

As a bonus, I'd like to offer kind of a different solution to your issue. You seem to be dealing with nested dictionaries, which is usually tedious, especially when you have to check for existence of an inner key.

There are some interesting libraries regarding this on pypi, here is a quick search for you.

In your specific case, dict_digger seems suited.

>>> import dict_digger
>>> d = {
  'Apple': {'American':'16', 'Mexican':10, 'Chinese':5},
  'Grapes':{'Arabian':'25','Indian':'20'} 
}

>>> print(dict_digger.dig(d, 'Apple','American'))
16
>>> print(dict_digger.dig(d, 'Grapes','American'))
None
Flavian Hautbois
  • 2,940
  • 6
  • 28
  • 45
10

I know this is 8 years old, but no one seems to have actually read and answered the question.

You can call .values() on a dict to get a list of the inner dicts and thus access them by index.

>>> mydict = {
...  'Apple': {'American':'16', 'Mexican':10, 'Chinese':5},
...  'Grapes':{'Arabian':'25','Indian':'20'} }

>>>mylist = list(mydict.values())
>>>mylist[0]
{'American':'16', 'Mexican':10, 'Chinese':5},
>>>mylist[1]
{'Arabian':'25','Indian':'20'}

>>>myInnerList1 = list(mylist[0].values())
>>>myInnerList1
['16', 10, 5]
>>>myInnerList2 = list(mylist[1].values())
>>>myInnerList2
['25', '20']
Jamie Marshall
  • 1,885
  • 3
  • 27
  • 50
  • 2
    interesting, I tried this and got `'dict_values' object does not support indexing `. Guess this answer needs an update since you need to wrap dict_values to recover a list – Yuca Oct 28 '19 at 19:34
  • 1
    @Yucca - You were correct, I didn't test my code. The answer has been updated – Jamie Marshall Feb 12 '20 at 17:49
9

You can use mydict['Apple'].keys()[0] in order to get the first key in the Apple dictionary, but there's no guarantee that it will be American. The order of keys in a dictionary can change depending on the contents of the dictionary and the order the keys were added.

François B.
  • 1,096
  • 7
  • 19
Gabe
  • 84,912
  • 12
  • 139
  • 238
5

You can't rely on order of dictionaries, but you may try this:

mydict['Apple'].items()[0][0]

If you want the order to be preserved you may want to use this: http://www.python.org/dev/peps/pep-0372/#ordered-dict-api

François B.
  • 1,096
  • 7
  • 19
4

Few people appear, despite the many answers to this question, to have pointed out that dictionaries are un-ordered mappings, and so (until the blessing of insertion order with Python 3.7) the idea of the "first" entry in a dictionary literally made no sense. And even an OrderedDict can only be accessed by numerical index using such uglinesses as mydict[mydict.keys()[0]] (Python 2 only, since in Python 3 keys() is a non-subscriptable iterator.)

From 3.7 onwards and in practice in 3,6 as well - the new behaviour was introduced then, but not included as part of the language specification until 3.7 - iteration over the keys, values or items of a dict (and, I believe, a set also) will yield the least-recently inserted objects first. There is still no simple way to access them by numerical index of insertion.

As to the question of selecting and "formatting" items, if you know the key you want to retrieve in the dictionary you would normally use the key as a subscript to retrieve it (my_var = mydict['Apple']).

If you really do want to be able to index the items by entry number (ignoring the fact that a particular entry's number will change as insertions are made) then the appropriate structure would probably be a list of two-element tuples. Instead of

mydict = {
  'Apple': {'American':'16', 'Mexican':10, 'Chinese':5},
  'Grapes':{'Arabian':'25','Indian':'20'} }

you might use:

mylist = [
    ('Apple', {'American':'16', 'Mexican':10, 'Chinese':5}),
    ('Grapes', {'Arabian': '25', 'Indian': '20'}
]

Under this regime the first entry is mylist[0] in classic list-endexed form, and its value is ('Apple', {'American':'16', 'Mexican':10, 'Chinese':5}). You could iterate over the whole list as follows:

for (key, value) in mylist:  # unpacks to avoid tuple indexing
    if key == 'Apple':
        if 'American' in value:
            print(value['American'])

but if you know you are looking for the key "Apple", why wouldn't you just use a dict instead?

You could introduce an additional level of indirection by cacheing the list of keys, but the complexities of keeping two data structures in synchronisation would inevitably add to the complexity of your code.

holdenweb
  • 33,305
  • 7
  • 57
  • 77
3

Simple Example to understand how to access elements in the dictionary:-

Create a Dictionary

d = {'dog' : 'bark', 'cat' : 'meow' } 
print(d.get('cat'))
print(d.get('lion'))
print(d.get('lion', 'Not in the dictionary'))
print(d.get('lion', 'NA'))
print(d.get('dog', 'NA'))

Explore more about Python Dictionaries and learn interactively here...

Community
  • 1
  • 1
Manish Methani
  • 245
  • 2
  • 7
1

With the following small function, digging into a tree-shaped dictionary becomes quite easy:

def dig(tree, path):
    for key in path.split("."):
        if isinstance(tree, dict) and tree.get(key):
            tree = tree[key]
        else:
            return None
    return tree

Now, dig(mydict, "Apple.Mexican") returns 10, while dig(mydict, "Grape") yields the subtree {'Arabian':'25','Indian':'20'}. If a key is not contained in the dictionary, dig returns None.

Note that you can easily change (or even parameterize) the separator char from '.' to '/', '|' etc.

1

In order to access an element of a nested dict, like the one in place of 'American' in your example dict, you may turn the dict and then the nested dicts into the lists of tuples:

mydict_list = list(mydict.items())

or

mydict_list = [*mydict.items()]

and the nested dicts:

nest_dict_list = [[*mydict_list[i][1].items()] for i in range(len(mydict_list))]

so then the element in place of 'American' is accessible with:

nest_dict_list[0][0][0]
sotmot
  • 1,256
  • 2
  • 9
  • 21
vlamet
  • 11
  • 3
0
mydict = {
'Apple': {'American':'16', 'Mexican':10, 'Chinese':5},
'Grapes':{'Arabian':'25','Indian':'20'} }

for n in mydict:
    print(mydict[n])
AhmedSeaf
  • 221
  • 2
  • 3