如何统计嵌套字典中的所有元素?

25 投票
10 回答
38598 浏览
提问于 2025-04-16 09:19

我该怎么高效地计算一个嵌套字典中的子元素数量呢?我发现len()函数的表现和我最开始想的不太一样:

>>> food_colors = {'fruit': {'orange': 'orange', 'apple': 'red', 'banana': 'yellow'}, 'vegetables': {'lettuce': 'green', 'beet': 'red', 'pumpkin': 'orange'}}
>>> len(food_colors)
2
>>>

如果我实际上想要计算子元素的数量(比如,期望的结果是“6”),有没有比逐个遍历每个元素并累加子元素数量更好的方法呢?在这个特定的应用中,我大约有五百万个子元素需要计算,每一次计算都很重要。

10 个回答

6

针对你的具体问题,你可以直接使用这个:

>>> d={'fruit': 
         {'orange': 'orange', 'apple': 'red', 'banana': 'yellow'}, 
       'vegetables': 
         {'lettuce': 'green', 'beet': 'red', 'pumpkin': 'orange'}}
>>> len(d)
2            # that is 1 reference for 'fruit' and 1 for 'vegetables'
>>> len(d['fruit'])
3            # 3 fruits listed...
>>> len(d['vegetables'])
3            # you thought of three of those...
>>> len(d['fruit'])+len(d['vegetables'])
6

虽然你可以用Python的各种工具来计算这个简单字典里的元素数量,但更有趣和更有成效的做法是先考虑一下数据的结构。

Python的基本数据结构有列表、集合、元组和字典。这些数据结构都可以通过引用“包含”自己或者其他数据结构的嵌套版本。

这个列表就是一个嵌套列表

>>> l = [1, [2, 3, [4]], [5, 6]]
>>> len(l)
3
>>> l[0]
1
>>> l[1]
[2, 3, [4]]
>>> l[2]
[5, 6]

第一个元素是整数1。元素1和2本身也是列表。其他基本的Python数据结构也可以这样嵌套。这些被称为递归数据结构。你可以用pprint来打印它们。

如果你能稍微整理一下你的字典,用Python最简单的工具提取信息就会容易得多:

>>> color='color'
>>> family='family'
>>> sensation='sensation'
>>> good_things={   
            'fruit': 
            {
                'orange': 
                    {
                    color: 'orange', 
                    family: 'citrus',
                    sensation: 'juicy'
                    }, 
                'apple': 
                    {
                    color: ['red','green','yellow'], 
                    family:'Rosaceae',
                    'sensation': 'woody'
                    },
                'banana': 
                    {
                    color: ['yellow', 'green'],
                    family: 'musa',
                    sensation: 'sweet'
                    }
            },
            'vegatables': 
            {
                'beets': 
                    {
                    color: ['red', 'yellow'],
                    family: 'Chenopodiaceae',
                    sensation: 'sweet'
                    },
                'broccoli':
                    {
                    color: 'green',
                    family: 'kale',
                    sensation: 'The butter you put on it',
                    }
            }
        }    

现在对这些数据的查询就更有意义了:

>>> len(good_things)
2                        # 2 groups: fruits and vegetables
>>> len(good_things['fruit'])
3                        # three fruits cataloged
>>> len(good_things['vegetables'])
2                        # I can only think of two vegetables...
>>> print good_things['fruit']['apple']
{'color': ['red', 'green', 'yellow'], 'sensation': 'woody', 'family': 'Rosaceae'}
>>> len(good_things['fruit']['apple']['color'])
3                        # apples have 3 colors
14

任意深度,一行代码:

def count(d):
    return sum([count(v) if isinstance(v, dict) else 1 for v in d.values()])
20

每个顶层的键值是否保证是一个字典,并且没有第二层的键值是字典?如果是这样的话,这样的操作会快得让你满意:

sum(len(v) for v in food_colors.itervalues())

如果数据结构更复杂,那就需要更多的代码了。当然,我不知道有什么内置的方法可以用来深入遍历复杂的数据结构。

撰写回答