26

Given a python dictionary and an integer n, I need to access the nth key. I need to do this repeatedly many times in my project.

I have written a function which does this:

def ix(self,dict,n):
    count=0
    for i in sorted(dict.keys()):
        if n==count:
            return i
        else:
            count+=1

But the problem is that if the dictionary is huge, the time complexity increases when used repeatedly.

Is there an efficient way to do this?

robinCTS
  • 5,746
  • 14
  • 30
  • 37
Hemanth Malla
  • 405
  • 1
  • 5
  • 9
  • Firstly remove `.keys()` for equivalent but faster code – jamylak Jun 07 '13 at 06:11
  • 17
    there's nothing like "the nth element" in an unordered collection. you are phrasing the problem wrong I think. – Elazar Jun 07 '13 at 06:12
  • @jamylak Ya, Thank you! I did't know that iteration can be done even without .keys(), and is there a solution for the main question? – Hemanth Malla Jun 07 '13 at 06:19
  • @HemanthMalla what is your question? – Elazar Jun 07 '13 at 06:19
  • What's the problem you actually want to solve? Conceptually, the "nth key of a dict" makes no sense, as a few other people have pointed out. You may be suffering from the [XY problem](http://meta.stackexchange.com/a/66378/201929). – Zero Piraeus Jun 07 '13 at 06:23
  • I am implementing a btree using python dictionaries,so i sorted the keys, now i need to do few manipulations on the middle element and the elements on the left and right of middle element, so i need to index through the keys..did i make my question clear? @Elazar, sorry for not being clear! – Hemanth Malla Jun 07 '13 at 06:32
  • 2
    use [ordered dict](http://docs.python.org/2/library/collections.html#collections.OrderedDict) and the methods describe in the answers. – Elazar Jun 07 '13 at 06:36
  • 2
    @Elazar: as of Python 3.6/3.7 you no longer need OrderedDict, dicts guarantee insertion order (and as a language feature in 3.7). – smci Mar 13 '19 at 05:51

4 Answers4

16

I guess you wanted to do something like this, but as dictionary don't have any order so the order of keys in dict.keys can be anything:

def ix(self, dct, n): #don't use dict as  a variable name
   try:
       return list(dct)[n] # or sorted(dct)[n] if you want the keys to be sorted
   except IndexError:
       print 'not enough keys'
Ashwini Chaudhary
  • 244,495
  • 58
  • 464
  • 504
15

dict.keys() returns a list so, all you need to do is dict.keys()[n]

But, a dictionary is an unordered collection so nth element does not make any sense in this context.

Note: Indexing dict.keys() is not supported in python3

Ch3steR
  • 20,090
  • 4
  • 28
  • 58
shyam
  • 9,134
  • 4
  • 29
  • 44
8

For those that want to avoid the creation of a new temporary list just to access the nth element, I suggest to use an iterator.

from itertools import islice
def nth_key(dct, n):
    it = iter(dct)
    # Consume n elements.
    next(islice(it, n, n), None) 
    # Return the value at the current position.
    # This raises StopIteration if n is beyond the limits.
    # Use next(it, None) to suppress that exception.
    return next(it)

This can be notably faster for very large dictionaries compared to converting the keys into a temporary list first and then accessing its nth element.

normanius
  • 8,629
  • 7
  • 53
  • 83
1

It is mentioned in multiple answers, that dictionaries were unordered. This is nonly true for python versions up to 3.6. From 3.7 ongoing, dictionaries are in fact ordered.

Andreas
  • 31
  • 2