繁体   English   中英

在列表字典中查找键的索引

[英]Find index of the key in a dictionary of list

给定一个列表字典

node_to_index = {"global": [0],
                  "l_eye": list(range(42, 48)),
                  "r_eye": list(range(36, 42)),
                  "l_brow": list(range(22, 27)),
                  "r_brow": list(range(17, 22)),
                  "mouth": list(range(48, 68)),
                  "nose": list(range(27, 35)),
                 }

给定一个数字,例如 37,它将返回“r_eye”键的索引,即 2

我会使用生成器表达式和enumerate ,只要条件满足,就使用next快捷方式:

next((ix for ix, (_,v) in enumerate(node_to_index.items()) if 37 in v), None)
# 2

请注意,对于 3.7 以下的 python 版本,不保留字典的插入顺序。 所以你应该考虑使用collections.OrderedDict

from collections import OrderedDict

node_to_index = OrderedDict({
    "global": [0],
    "l_eye": list(range(42, 48)),
    "r_eye": list(range(36, 42)),
    "l_brow": list(range(22, 27)),
    "r_brow": list(range(17, 22)),
    "mouth": list(range(48, 68)),
    "nose": list(range(27, 35)),
})

next((ix for ix, (_,v) in enumerate(node_to_index.items()) if 37 in v), None)
# 2

您应该使用collections.OrderedDict来保证其顺序(索引)。

from collections import OrderedDict

node_to_index = OrderedDict({
    "global": [0],
    "l_eye": list(range(42, 48)),
    "r_eye": list(range(36, 42)),
    "l_brow": list(range(22, 27)),
    "r_brow": list(range(17, 22)),
    "mouth": list(range(48, 68)),
    "nose": list(range(27, 35)),
})


def find_index(target: int) -> int:
    for idx, value in enumerate(node_to_index.values()):
        if target in value:
            return idx
    return -1


print(find_index(37))

输出:

2

笔记

如果您使用早于 3.6 的 CPython 或早于 3.7 的其他解释器,则即使创建也不能保证dict顺序。 所以这样做:

node_to_index = OrderedDict([
    ('global', [0]),
    ('l_eye', list(range(42, 48))),
    ('r_eye', list(range(36, 42))),
    ('l_brow', list(range(22, 27))),
    ('r_brow', list(range(17, 22))),
    ('mouth', list(range(48, 68))),
    ('nose', list(range(27, 35))),
])

缺勤政策

这不是相对于 OP 的问题,而是附加在评论中。
对于缺少目标值,您有三个选项。

return -1
raise ValueError(f'{target} is not found')
return None

请注意,如果函数在某些情况下return None ,则 PEP8 不建议省略其他情况下的return None

您只需遍历项目,直到 37 位于与该键关联的列表中。

请注意,您必须处理边缘情况,例如如果多个列表包含数字(当前它是返回的第一个列表)或没有列表包含它(当前它返回None ),该怎么办。

def find_number(number, my_dict):
    for n, (key, value) in enumerate(my_dict.items()):
        if number in value:
            return n

node_to_index = {"global": [0],
                 "l_eye": list(range(42, 48)),
                 "r_eye": list(range(36, 42)),
                 "l_brow": list(range(22, 27)),
                 "r_brow": list(range(17, 22)),
                 "mouth": list(range(48, 68)),
                 "nose": list(range(27, 35)),
                }

find_number(37, node_to_index) # returns 2
node_to_index = {"global": [0],
                 "l_eye": list(range(42, 48)),
                 "r_eye": list(range(36, 42)),
                 "l_brow": list(range(22, 27)),
                 "r_brow": list(range(17, 22)),
                 "mouth": list(range(48, 68)),
                 "nose": list(range(27, 35)),
                 }


def get_key(val):
    pos = 0
    for key, value in node_to_index.items():
         for elem in value:
             if elem == val:
                 return pos
         pos += 1


print(get_key(27))


如果您确定该值存在于其中一个列表中,您可以在列表推导式上使用 index() 方法:

value = 37
index = [value in nodes for nodes in node_to_index.values()].index(True)

print(index) # 2 

请注意,为此使用字典可能不是最佳选择。 您似乎只需要一个元组列表。 这将使索引更加可靠和有意义:

node_to_index = [ ( "global", [0]),
                  ( "l_eye",  list(range(42, 48) ),
                  ( "r_eye",  list(range(36, 42) ),
                  ( "l_brow", list(range(22, 27) ),
                  ( "r_brow", list(range(17, 22) ),
                  ( "mouth",  list(range(48, 68) ),
                  ( "nose",   list(range(27, 35) )
                ]

value = 37
index = [value in nodes for _,nodes in node_to_index].index(True)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM