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

Python 如何计算嵌套字典中的所有元素?,python,Python,如何以最有效的方式计算嵌套字典中的子元素数?len()函数的工作方式与我最初预期的不同: >>> food_colors = {'fruit': {'orange': 'orange', 'apple': 'red', 'banana': 'yellow'}, 'vegetables': {'lettuce': 'green', 'beet': 'red', 'pumpkin': 'orange'}} >>> len(food_colors) 2 >&g

如何以最有效的方式计算嵌套字典中的子元素数?len()函数的工作方式与我最初预期的不同:

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

如果我真的想计算子元素的数量呢?(例如,预期结果为“6”)有没有更好的方法来实现这一点,而不是遍历每个元素并求和子元素的数量?在这个特定的应用程序中,我有大约500万个子元素要计数,每个时钟周期计数。

是否保证每个顶级键都有一个字典作为其值,并且没有第二级键有字典?如果是这样,这将以您希望的速度进行:

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

如果数据结构更复杂,当然需要更多的代码。我不知道有什么内在因素可以进行深层次的数据结构漫游。

您只想要直系子女吗?如果是这样,这可能是最好的:

sum(len(x) for x in food_colors.values())
sum(len(x) for x in fc.values())

子元素是不同的对象,没有比在它们上迭代更快的关系可以使用-尽管有很多方法可以做到这一点(例如使用
map
,或
.values()
),但性能会有所不同,足够让您可能想使用
timeit
来比较它们

如果对它们进行计数对应用程序很重要,请考虑做一些事情使之更容易:

  • 在构建数据结构时计算它们
  • <> LI>而不是嵌套<代码> DICT s,考虑内存中的代码> SQLite 表,使用<代码> Connect(“:内存:”)<代码>(这可能会减慢其他操作,或者使它们更复杂,但权衡是值得考虑的)。
对于您的具体问题,您可以使用以下选项:

>>> 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的基本数据结构如下所示。这些数据结构中的任何一个都可以通过引用“保存”自身或其他数据结构的任何嵌套版本

此列表是:

第一个元素是整数1。元素1和2本身就是列表。对于任何其他基本Python数据结构也是如此。这些是。你可以用打印机打印出来

如果您能更好地组织字典,那么使用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

您可以使用递归函数来实现这一点

>>> x
{'a': 1, 'b': 2, 'c': 3, 'd': {'I': 1, 'II': 2, 'III': 3}, 'e': 5}
>>> def test(d):
...   cnt = 0
...   for e in d:
...     if type(d[e]) is dict:
...       cnt += test(d[e])
...     else:
...       cnt += 1
...   return cnt
...
>>> test(x)
7

对于任意深度嵌套字典:

def num_elements(x):
  if isinstance(x, dict):
    return sum([num_elements(_x) for _x in x.values()])
  else: return 1

任意深度,一个衬垫:

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

方括号是不必要的,在这种情况下可能会减慢速度。
len(食物颜色['fruit'])+len(食物颜色['fruit'])
?在Python 3中,只需使用:
sum(len(v)表示食物颜色中的v.values())
def num_elements(x):
  if isinstance(x, dict):
    return sum([num_elements(_x) for _x in x.values()])
  else: return 1
def count(d):
    return sum([count(v) if isinstance(v, dict) else 1 for v in d.values()])