【问题标题】:Extracting values from Dictionary of lists with nested dictionaries从具有嵌套字典的列表字典中提取值
【发布时间】:2020-09-14 10:46:05
【问题描述】:

编辑: 我修改了之前写的代码,因为字典列表中的键名是一样的。

我目前必须使用具有这种形式的嵌套字典:

r = {'keyX': [{'keyAa': valueAa,
               'keyAb': valueAb,
               'keyAc': {'keyAca': {'keyAcaa': valueAcaa
                                    'keyAcab': valueAcab
                                    'keyAcac': valueAcac
                                     ...}}
               'keyAd': valueAd
               'keyAe': valueAe 
              }
              {'keyAa': valueBa,
               'keyAb': valueBb,
               'keyAc': {'keyAca': {'keyAcaa': valueBcaa
                                    'keyAcab': valueBcab
                                    'keyAcac': valueBcac
                                     ...}}
               'keyAd': valueBd
               'keyAe': valueBe 
              }
              ...
             ]
    'keyY': {'key1a': value1a
             'key1b': value1b
             ...}}

我想找到 keyAcac 的最大值。 (不同字典的键名相同) 为了获得最大值,我尝试在 max() 函数之前使用 int():

max_volume = max(int(r['keyX']['keyAc']['keyAca']['KeyAcac'])))

或:

max_volume = max(int(r['keyX']['keyAc']['keyAca']['KeyAcac']) for a in a.values())

以各种方式执行此操作,但我总是得到“TypeError:列表索引必须是整数或切片,而不是 str”错误,我无法解决这个问题。你能帮帮我吗?

一旦找到这个最大值,我还想返回所有具有相同主字母的键和值的字典。 (例如:如果最大值是 valueBcac,我希望输出 keyBa、keyBb、keyBc、...,以及它们的所有值)。这可能吗?

【问题讨论】:

  • 请用您尝试过的代码更新您的问题。
  • 我编辑了一个我之前写错的重大更改:键名(例如,keyAcac 在不同的字典中是相同的)

标签: python python-3.x list dictionary nested


【解决方案1】:

是的,您可以使用递归生成器函数遍历嵌套结构,生成“路径”。您的原始示例有列表和字典,这也处理了任何可能的集合(无论如何)。

之后,您可以简单地将内置 max() 函数与该迭代器一起使用。

r = {
    "keyX": [
        {
            "keyAa": 123,
            "keyAb": 543,
            "keyAc": {
                "keyAca": {
                    "keyAcaa": 635,
                    "keyAcab": 234,
                    "keyAcac": 753,
                }
            },
            "keyAd": 5753,
            "keyAe": 12312,
        },
        {
            "keyBa": 642,
            "keyBb": 753,
            "keyBc": {
                "keyBca": {
                    "keyBcaa": 25472,
                    "keyBcab": 75311,
                    "keyBcac": 23432,
                }
            },
            "keyBd": 2362,
            "keyBe": 742,
        },
    ],
    "keyY": {"key1a": 12321, "key1b": 66421},
}


def iterate_nested(s, path=()):
    if isinstance(s, (list, tuple)):
        for index, value in enumerate(s):
            yield from iterate_nested(value, path + (index,))
    elif isinstance(s, dict):
        for key, value in s.items():
            yield from iterate_nested(value, path + (key,))
    elif isinstance(s, set):
        for value in s:
            # just mark that it's some set item with `set`
            yield from iterate_nested(value, path + (set,))
    else:
        yield (path, s)

# For debugging:
for path, value in iterate_nested(r):
    print(path, value)

# For the actual problem:
highest_value_and_path = max(
    iterate_nested(r), key=lambda pair: pair[1]
)
print("Highest:", highest_value_and_path)

输出例如

~/Desktop $ python3 so63882758.py
('keyX', 0, 'keyAa') 123
('keyX', 0, 'keyAb') 543
('keyX', 0, 'keyAc', 'keyAca', 'keyAcaa') 635
('keyX', 0, 'keyAc', 'keyAca', 'keyAcab') 234
('keyX', 0, 'keyAc', 'keyAca', 'keyAcac') 753
('keyX', 0, 'keyAd') 5753
('keyX', 0, 'keyAe') 12312
('keyX', 1, 'keyBa') 642
('keyX', 1, 'keyBb') 753
('keyX', 1, 'keyBc', 'keyBca', 'keyBcaa') 25472
('keyX', 1, 'keyBc', 'keyBca', 'keyBcab') 75311
('keyX', 1, 'keyBc', 'keyBca', 'keyBcac') 23432
('keyX', 1, 'keyBd') 2362
('keyX', 1, 'keyBe') 742
('keyY', 'key1a') 12321
('keyY', 'key1b') 66421
Highest: (('keyX', 1, 'keyBc', 'keyBca', 'keyBcab'), 75311)

【讨论】:

  • 谢谢,但我编辑了这个问题,但我之前写错了一个重大更改:列表中不同字典中的键具有相同的名称。示例:keyAcac 在字典中同名,并且没有 keyBcac。
  • 没关系——通过这个实现,无论如何你都可以获得通过嵌套结构的完整路径。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-28
  • 1970-01-01
  • 2021-06-02
  • 2023-02-04
  • 1970-01-01
  • 2020-01-21
相关资源
最近更新 更多