在Python中,如何获取下一个和上一个键:字典中特定键的值?

时间:2015-01-19 23:43:47

标签: python dictionary key

好的,所以这有点难以解释,但这里有:

我有一本字典,我正在添加内容。内容是带有IP地址(值)的哈希用户名(密钥)。 我通过在基数16上运行它们然后使用Collection.orderedDict将哈希放入一个顺序。 所以,字典看起来有点像这样:

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

我需要的是一种机制,允许我选择其中一个键,并使键/值项目更高,更低一个。因此,例如,如果我选择2345,代码将返回键:值组合' 1234:8.8.8.8'和' 3213:4.4.4.4'

所以,比如:

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

10 个答案:

答案 0 :(得分:4)

OrderedDict source code所示, 如果你有一把钥匙,你想在O(1)中找到下一个和上一个,你就是这样做的。

>>> from collections import OrderedDict
>>> d = OrderedDict([('aaaa', 'a',), ('bbbb', 'b'), ('cccc', 'c'), ('dddd', 'd'), ('eeee', 'e'), ('ffff', 'f')])
>>> i = 'eeee'
>>> link_prev, link_next, key = d._OrderedDict__map['eeee']
>>> print 'nextKey: ', link_next[2], 'prevKey: ', link_prev[2]
nextKey:  ffff prevKey:  dddd

这将通过广告订单为您提供下一个和上一个。如果您以随机顺序添加项目,则只需按排序顺序跟踪您的项目。

答案 1 :(得分:2)

编辑: OP现在声明他们正在使用OrderedDicts,但用例仍然需要这种方法。

由于没有订购dicts,您无法直接执行此操作。在您的示例中,您尝试引用该项目,就像使用链接列表一样。

快速解决方案是提取密钥并对其进行排序,然后迭代该列表:

keyList=sorted(d.keys())
for i,v in enumerate(keyList):
    if v=='eeee':
        print d[keyList[i+1]]
        print d[keyList[i-1]]

keyList保存您商品的订单,您必须返回该商品才能找到下一个/上一个键获取下一个/上一个值的内容。您还必须检查i + 1是否大于列表长度且i-1小于0。

您可以类似地使用OrderedDict,但我相信您仍需要使用单独的列表执行上述操作,因为OrderedDict没有next / prev方法。

答案 2 :(得分:2)

您可以使用基于迭代器的泛型函数来获取移动窗口(取自this问题):

import itertools

def window(iterable, n=3):
    it = iter(iterable)
    result = tuple(itertools.islice(it, n))
    if len(result) == n:
        yield result
    for element in it:
        result = result[1:] + (element,)
        yield result

l = range(8)
for i in window(l, 3):
    print i

将上述功能与OrderedDict.items()一起使用,将按顺序为您提供三个(键,值)对:

d = collections.OrderedDict(...)

for p_item, item, n_item in window(d.items()):
    p_key, p_value = p_item
    key, value = item
    # Or, if you don't care about the next value:
    n_key, _ = n_item

当然使用此函数时,第一个和最后一个值永远不会处于中间位置(尽管这对于某些调整来说并不困难)。

我认为最大的优势是它不需要在前一个和下一个键中进行表查找,而且它是通用的并且适用于任何可迭代的。

答案 3 :(得分:1)

尝试:

pos = 0
d = {'aaaa': 'a', 'bbbb':'b', 'cccc':'c', 'dddd':'d', 'eeee':'e', 'ffff':'f'}

for i in d:
    pos+=1
    if i == 'eeee':
        listForm = list(d.values())
        print(listForm[pos-1])
        print(listForm[pos+1])

正如@ AdamKerz的回答enumerate似乎是pythonic,但如果你是初学者,这段代码可能会帮助你以一种简单的方式理解它。

而且我觉得它比排序后更快+更小,然后建立列表&amp;然后枚举

答案 4 :(得分:1)

您也可以使用list.index()方法。

这个函数更通用(你可以检查位置+ n和-n),它会捕获搜索不在dict中的键的尝试,并且如果有的话,它也将返回None在密钥之后没有任何事情:

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)

答案 5 :(得分:1)

也许这是一种矫枉过正,但您可以使用帮助程序类跟踪插入的键,并根据该列表,您可以检索上一个或下一个键。如果对象已经是第一个或最后一个元素,请不要忘记检查边界条件。这样,您就不需要总是求助于有序列表或搜索元素。

from collections import OrderedDict

class Helper(object):
    """Helper Class for Keeping track of Insert Order"""
    def __init__(self, arg):
        super(Helper, self).__init__()

    dictContainer = dict()
    ordering = list()

    @staticmethod
    def addItem(dictItem):
        for key,value in dictItem.iteritems():
            print key,value
            Helper.ordering.append(key)
            Helper.dictContainer[key] = value

    @staticmethod
    def getPrevious(key):
        index = (Helper.ordering.index(key)-1)
        return Helper.dictContainer[Helper.ordering[index]]


#Your unordered dictionary
d = {'aaaa': 'a', 'bbbb':'b', 'cccc':'c', 'dddd':'d', 'eeee':'e', 'ffff':'f'}

#Create Order over keys
ordered = OrderedDict(sorted(d.items(), key=lambda t: t[0]))

#Push your ordered list to your Helper class
Helper.addItem(ordered)


#Get Previous of    
print Helper.getPrevious('eeee')
>>> d

答案 6 :(得分:1)

您可以在之前的temp变量中存储键和值,并可以使用索引访问上一个和下一个键值对。

它非常动态,适用于您查询的任何键。请检查此代码:

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'}
ch = raw_input('Pleasure Enter your choice : ')
keys = d.keys()
values = d.values()
#print keys, values
for k,v in d.iteritems():
    if k == ch:
        ind = d.keys().index(k)
        print keys[ind-1], ':',values[ind-1]
        print keys[ind+1], ':',values[ind+1]

答案 7 :(得分:0)

我认为这是使用lambdalist comprehension解决问题的一种不错的Python方法,尽管在执行时间上可能不是最佳选择:

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

答案 8 :(得分:0)

另一种简单明了的方法:此函数返回距 k

offset 位置的键。
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    

答案 9 :(得分:-1)

我知道如何获取下一个键:字典中特定键的值:

flag = 0
for k, v in dic.items():
    if flag == 0:
        code...
        flag += 1
        continue
    code...{next key and value in for}