In Python, How can I get the next and previous key

2020-06-08 02:14发布

Okay, so this is a little hard to explain, but here goes:

I have a dictionary, which I'm adding content to. The content is a hashed username (key) with an IP address (value). I was putting the hashes into an order by running them against base 16, and then using Collection.orderedDict. So, the dictionary looked a little like this:

d = {'1234': '8.8.8.8', '2345':'0.0.0.0', '3213':'4.4.4.4', '4523':'1.1.1.1', '7654':'1.3.3.7', '9999':'127.0.0.1'}

What I needed was a mechanism that would allow me to pick one of those keys, and get the key/value item one higher and one lower. So, for example, If I were to pick 2345, the code would return the key:value combinations '1234:8.8.8.8' and '3213:4.4.4.4'

So, something like:

for i in d:
  while i < len(d)
   if i == '2345':
     print i.nextItem
     print i.previousItem
     break()

9条回答
不美不萌又怎样
2楼-- · 2020-06-08 02:53

Another way that seems simple and straight forward: this function returns the key which is offset positions away from k

def get_shifted_key(d:dict, k:str, offset:int) -> str:
    l = list(d.keys())
    if k in l:
        i = l.index(k) + offset
        if 0 <= i < len(l):
            return l[i]
    return None    
查看更多
姐就是有狂的资本
3楼-- · 2020-06-08 02:54

I think this is a nice Pythonic way of resolving your problem using a lambda and list comprehension, although it may not be optimal in execution time:

import collections

x = collections.OrderedDict([('a','v1'),('b','v2'),('c','v3'),('d','v4')])

previousItem = lambda currentKey, thisOrderedDict : [
    list( thisOrderedDict.items() )[ z - 1 ] if (z != 0) else None
    for z in range( len( thisOrderedDict.items() ) )
    if (list( thisOrderedDict.keys() )[ z ] == currentKey) ][ 0 ]

nextItem = lambda currentKey, thisOrderedDict : [
    list( thisOrderedDict.items() )[ z + 1 ] if (z != (len( thisOrderedDict.items() ) - 1)) else None
    for z in range( len( thisOrderedDict.items() ) )
    if (list( thisOrderedDict.keys() )[ z ] == currentKey) ][ 0 ]

assert previousItem('c', x) == ('b', 'v2')
assert nextItem('c', x) == ('d', 'v4')
assert previousItem('a', x) is None
assert nextItem('d',x) is None
查看更多
孤傲高冷的网名
4楼-- · 2020-06-08 02:56

You could also use the list.index() method.

This function is more generic (you can check positions +n and -n), it will catch attempts at searching a key that's not in the dict, and it will also return None if there's nothing before of after the key:

def keyshift(dictionary, key, diff):
    if key in dictionary:
        token = object()
        keys = [token]*(diff*-1) + sorted(dictionary) + [token]*diff
        newkey = keys[keys.index(key)+diff]
        if newkey is token:
            print None
        else:
            print {newkey: dictionary[newkey]}
    else:
        print 'Key not found'


keyshift(d, 'bbbb', -1)
keyshift(d, 'eeee', +1)
查看更多
登录 后发表回答