【问题标题】:Accessing value inside nested dictionaries [duplicate]访问嵌套字典中的值[重复]
【发布时间】:2012-05-11 02:13:59
【问题描述】:

我是 python 新手,需要帮助解决问题:

我有一本像

这样的字典
tmpDict = {'ONE':{'TWO':{'THREE':10}}}

除了做之外,我们还有其他方法可以获取 THREE 的价值吗

tmpDict['ONE']['TWO']['THREE']

?

【问题讨论】:

  • 你为什么有一本这样的字典开头?您还希望以一种简单的方式访问每个级别的其他多少数据?
  • 你为什么不想做tmpDict['ONE']['TWO']['THREE']

标签: python dictionary


【解决方案1】:

在 python 中,当然有几种方法可以做到这一点,但有一种显而易见的方法。

tmpdict["ONE"]["TWO"]["THREE"] 显而易见的方法。

当这不适合您的算法时,这可能暗示您的结构不是最适合解决问题的。

如果您只想省去重复输入,当然可以为 dict 的子集设置别名:

>>> two_dict = tmpdict['ONE']['TWO'] # now you can just write two_dict for tmpdict['ONE']['TWO']
>>> two_dict["spam"] = 23
>>> tmpdict
{'ONE': {'TWO': {'THREE': 10, 'spam': 23}}}

【讨论】:

  • 没错,通过[] 操作符访问字典的元素是一种显而易见的方式。但我强烈建议您也阅读this answer 的相关问题。在现实场景中,必须将“路径”(可能是可变长度)传递给(可能很深)嵌套字典中的元素,在每个中间字典上调用 get()[] 运算符会很麻烦.
  • 但是您不能为别名设置别名,因此如果您打算以递归方式多次执行该过程,则必须拥有密钥,否则它将第二次按值传递.
【解决方案2】:

您可以在每个字典上使用 get()。确保您已为每个访问添加了无检查。

【讨论】:

  • .get 不是用于事后检查返回值是否为None,您也可以只检查键是否在字典中:key in dict 或旧版本dict.has_key跨度>
  • tmpDict.get('ONE', {}).get('TWO', {}).get('THREE') 默认使用带有空字典的get ...如果三个键中的任何一个不存在,它将返回None
  • @dav1d 为什么说 .get 不是用于事后检查的,返回值是否为 None?为什么还会存在这种方法?
【解决方案3】:

我的实现:

def get_nested(data, *args):
    if args and data:
        element  = args[0]
        if element:
            value = data.get(element)
            return value if len(args) == 1 else get_nested(value, *args[1:])

示例用法:

>>> dct={"foo":{"bar":{"one":1, "two":2}, "misc":[1,2,3]}, "foo2":123}
>>> get_nested(dct, "foo", "bar", "one")
1
>>> get_nested(dct, "foo", "bar", "two")
2
>>> get_nested(dct, "foo", "misc")
[1, 2, 3]
>>> get_nested(dct, "foo", "missing")
>>>

在缺少键的情况下不会引发异常,在这种情况下返回 None 值。

【讨论】:

    【解决方案4】:

    Sivasubramaniam Arunachalam 或 ch3ka 已经给出了答案。

    我只是添加答案的性能视图。

    dicttest={}
    dicttest['ligne1']={'ligne1.1':'test','ligne1.2':'test8'}
    %timeit dicttest['ligne1']['ligne1.1']
    %timeit dicttest.get('ligne1').get('ligne1.1')
    

    给我们:

    每个循环 112 ns ± 29.7 ns(平均值 ± 标准偏差。7 次运行,每次 10000000 次循环)

    每个循环 235 ns ± 9.82 ns(平均值 ± 标准偏差,7 次运行,每次 1000000 次循环)

    【讨论】:

      【解决方案5】:

      不,那些是嵌套字典,所以这是唯一真正的方法(您可以使用get(),但本质上是一样的)。但是,还有另一种选择。您可以使用元组作为键来代替嵌套字典:

      tempDict = {("ONE", "TWO", "THREE"): 10}
      tempDict["ONE", "TWO", "THREE"]
      

      这确实有一个缺点,例如,没有(简单且快速)获取"TWO" 的所有元素的方法,但如果这无关紧要,这可能是一个很好的解决方案。

      【讨论】:

      • 我不太清楚这在任何实际应用中会有什么好处。如果您的数据是结构化的,那么将其展平并提高关键复杂性似乎并不能真正增加价值。
      • @sr2222 这意味着你不必有大量的dicts,这意味着你在添加新值时不必担心创建子字典,它可能会更多自然取决于应用程序。我认为这在某些情况下是值得的。
      猜你喜欢
      • 2018-02-07
      • 1970-01-01
      • 2020-10-03
      • 2012-07-26
      • 1970-01-01
      • 2013-09-29
      • 1970-01-01
      • 1970-01-01
      • 2014-09-13
      相关资源
      最近更新 更多