【问题标题】:Getting key of unique values in a nested dict within lists在列表中的嵌套字典中获取唯一值的键
【发布时间】:2016-12-27 13:07:51
【问题描述】:

我有一个字典,其中包含具有以下结构的元素

{'task0': {'id': 0, 'successor':[<other elements>]}

每个元素都包含一个唯一的 id 和所提及元素的后继列表。也可以为空,这意味着该元素没有后继。

示例

a = {'task0': {'node_id': 0, 'successor': [{'task1': {'node_id': 1, 'successor': [{'task2': {'node_id': 2, 'successor': [{'task4': {'node_id': 4, 'successor': []}}, {'task5': {'node_id': 5, 'successor': []}}]}},  {'task3': {'node_id': 3, 'successor': []}}]}}]}}

我想要什么

def get_node_name_by_id(obj, id_search)

示例:def get_node_name_by_id(a, 3) == 'task3'

def get_parent_id_by_child_id(obj, id_search)

示例:def get_parent_id_by_child_id(a, 3) == 1

我目前所拥有的

def get_node_name_by_id(obj, id_search):
    for k,v in obj.iteritems():
        if isinstance(v,dict):
            if v['node_id'] is id_search:
                return k
            elif v['successor']:
                    for e in v['successor']:
                        return get_node_name_by_id(e, id_search)

-> 问题:如果我正在搜索的 id 不在列表的第 1 位,我会得到 None 作为结果。

-> 对于第二个功能,我不知道如何实现它

问题

  • 我该如何分别解决我的问题,是否有更智能的方法来实现第一个功能?
  • 第二个函数的最佳实现是什么?

感谢您的帮助。

【问题讨论】:

  • 为什么 task1 和 task2 有 '[' ,它是字典中的列表吗?
  • 是的,包含字典的列表(也可以包含带有列表的字典)
  • if v['id'] is id ? is 而不是 in ?我不推荐id,因为它是保留关键字。请提供一个可验证的示例,其中包含您的 dict 中的真实数据。
  • @Jean-FrançoisFabre: id() 是一个内置函数,而不是关键字。如果您只想使用内置的,屏蔽它可能是个问题。
  • 你是对的。无论如何都不是一个好习惯(好吧,谁使用id?)

标签: python dictionary nested iteration


【解决方案1】:

我们之前没有看到的明显问题是您的内部循环中的无条件 return 语句。

只有当它不是None 时才需要返回,否则列表中除第一个之外的其他项目将被忽略。

(注意我已将iteritems 更改为items,因为它与python 3 兼容并且也适用于最新的python 2.7 版本)

a = {'task0': {'node_id': 0, 'successor': [{'task1': {'node_id': 1, 'successor': [{'task2': {'node_id': 2, 'successor': [{'task4': {'node_id': 4, 'successor': []}}, {'task5': {'node_id': 5, 'successor': []}}]}},  {'task3': {'node_id': 3, 'successor': []}}]}}]}}

def get_node_name_by_id(obj, id_search):
    for k,v in obj.items():
        if isinstance(v,dict):
            if v['node_id'] is id_search:
                return k
            elif v['successor']:
                    for e in v['successor']:
                        r = get_node_name_by_id(e, id_search)
                        if r:
                            return r


print(get_node_name_by_id(a, 3))

输出:

task3

【讨论】:

    【解决方案2】:

    根据 tobias_k 评论,我找到了一种更简单的方法来存储信息。 因为每个节点对象都有一个唯一的 ID,所以只存储这些 ID 就足够了。 每个子列表的索引是节点的索引,为其定义了后继者。

    successor_list = [[successors_node0], [successors_node1], [successors_node2], ..., [successors_nodeN]]
    

    借助ID,我可以访问节点对象(所有节点对象都存储在一个列表中)以访问对象属性。

    【讨论】:

      猜你喜欢
      • 2016-03-10
      • 2016-01-07
      • 2021-05-10
      • 2014-11-27
      • 1970-01-01
      • 2012-05-21
      • 2020-03-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多