Search code examples
pythondictionaryiteratorpython-3.8

Return next key of a given dictionary key, python 3.6+


I am trying to find a way to get the next key of a Python 3.6+ (which are ordered)

For example:

dict = {'one':'value 1','two':'value 2','three':'value 3'}

What I am trying to achieve is a function to return the next key. something like:

next_key(dict, current_key='two')   # -> should return 'three' 

This is what I have so far:

def next_key(dict,key):
    key_iter = iter(dict)  # create iterator with keys
    while k := next(key_iter):    #(not sure if this is a valid way to iterate over an iterator)
        if k == key:   
            #key found! return next key
            try:    #added this to handle when key is the last key of the list
                return(next(key_iter))
            except:
                return False
    return False

well, that is the basic idea, I think I am close, but this code gives a StopIteration error. Please help.

Thank you!


Solution

  • Looping while k := next(key_iter) doesn’t stop correctly. Iterating manually with iter is done either by catching StopIteration:

    iterator = iter(some_iterable)
    
    while True:
        try:
            value = next(iterator)
        except StopIteration:
            # no more items
    

    or by passing a default value to next and letting it catch StopIteration for you, then checking for that default value (but you need to pick a default value that won’t appear in your iterable!):

    iterator = iter(some_iterable)
    
    while (value := next(iterator, None)) is not None:
        # …
    
    # no more items
    

    but iterators are, themselves, iterable, so you can skip all that and use a plain ol’ for loop:

    iterator = iter(some_iterable)
    
    for value in iterator:
        # …
    
    # no more items
    

    which translates into your example as:

    def next_key(d, key):
        key_iter = iter(d)
    
        for k in key_iter:
            if k == key:
                return next(key_iter, None)
    
        return None