获取Python字典字典中所有键的数量

我有一个Python 2.7词典的字典。

我需要快速计算所有键的数量,包括每个词典中的键。

所以在这个例子中,我需要所有的键的数量是6:

dict_test = {'key2': {'key_in3': 'value', 'key_in4': 'value'}, 'key1': {'key_in2': 'value', 'key_in1': 'value'}} 

我知道我可以迭代循环中的每个键,但我正在寻找一个更快的方法来做到这一点,因为我将有成千上万的键,这样做是无效的:

 count_the_keys = 0 for key in dict_test.keys(): for key_inner in dict_test[key].keys(): count_the_keys += 1 # something like this would be more effective # of course .keys().keys() doesn't work print len(dict_test.keys()) * len(dict_test.keys().keys()) 

保持简单

如果我们知道所有的价值都是字典,而且不想检查它们的任何价值是否也是字典,那么它就像下面这样简单:

 len(dict_test) + sum(len(v) for v in dict_test.itervalues()) 

细化一下,在计算之前检查值是否是字典:

 len(dict_test) + sum(len(v) for v in dict_test.itervalues() if isinstance(v, dict)) 

最后,如果你想做一个任意的深度,如下所示:

 def sum_keys(d): return (0 if not isinstance(d, dict) else len(d) + sum(sum_keys(v) for v in d.itervalues()) print sum_keys({'key2': {'key_in3': 'value', 'key_in4': 'value'}, 'key1': {'key_in2': 'value', 'key_in1': dict(a=2)}}) # => 7 

在最后一种情况下,我们定义一个recursion调用的函数。 给定值d ,我们返回:

  • 如果该值不是字典,则为0 ; 要么
  • 字典中的键的数量,加上我们所有孩子中的键的总数。

让它更快

以上是一个简洁易懂的方法。 我们可以使用一个发生器快一点:

 def _counter(d): # how many keys do we have? yield len(d) # stream the key counts of our children for v in d.itervalues(): if isinstance(v, dict): for x in _counter(v): yield x def count_faster(d): return sum(_counter(d)) 

这使我们获得了更多的性能:

 In [1]: %timeit sum_keys(dict_test) 100000 loops, best of 3: 4.12 µs per loop In [2]: %timeit count_faster(dict_test) 100000 loops, best of 3: 3.29 µs per loop 

怎么样

 n = sum([len(v)+1 for k, v in dict_test.items()]) 

你正在做的是遍历所有的键k和值v。值是你的子句。 您将获得这些字典的长度并添加一个包含用于索引子字典的键。

之后,你总结列表获得完整的密钥数量。

编辑:

为了澄清,这个片段只适用于字典字典的问题。 不是词典字典的字典…
所以不要用它嵌套的例子:)

作为更一般的方法,您可以使用recursion函数和生成器expression式:

 >>> def count_keys(dict_test): ... return sum(1+count_keys(v) if isinstance(v,dict) else 1 for _,v in dict_test.iteritems()) ... 

例:

 >>> dict_test = {'a': {'c': '2', 'b': '1', 'e': {'f': {1: {5: 'a'}}}, 'd': '3'}} >>> >>> count(dict_test) 8 

注意 :在python 3.X中使用dict.items()方法而不是iteritems()

接受答案的基准表明这个函数比接受的答案快:

 from timeit import timeit s1 = """ def sum_keys(d): return 0 if not isinstance(d, dict) else len(d) + sum(sum_keys(v) for v in d.itervalues()) sum_keys(dict_test) """ s2 = """ def count_keys(dict_test): return sum(1+count_keys(v) if isinstance(v,dict) else 1 for _,v in dict_test.iteritems()) count_keys(dict_test) """ print '1st: ', timeit(stmt=s1, number=1000000, setup="dict_test = {'a': {'c': '2', 'b': '1', 'e': {'f': {1: {5: 'a'}}}, 'd': '3'}}") print '2nd : ', timeit(stmt=s2, number=1000000, setup="dict_test = {'a': {'c': '2', 'b': '1', 'e': {'f': {1: {5: 'a'}}}, 'd': '3'}}") 

结果:

 1st: 4.65556812286 2nd : 4.09120802879 

在Python 3.x中使用一个生成器函数和新语法的yield from 。 这将适用于任意嵌套的字典

 >>> from collections import Mapping >>> def count_keys(mydict): ... for key, value in mydict.items(): ... if isinstance(value, Mapping): ... yield from count_keys(value) ... yield len(mydict) ... >>> dict_test = {'key2': {'key_in3': 'value', 'key_in4': 'value'}, 'key1': {'key_in2': 'value', 'key_in1': 'value'}} >>> sum(count_keys(dict_test)) 6 

在Python 2.x中,您需要执行以下操作:

 >>> def count_keys(mydict): ... for key, value in mydict.items(): ... if isinstance(value, Mapping): ... for item in count_keys(value): ... yield 1 ... yield 1 ... >>> sum(count_keys(dict_test)) 6 

就像是:

print len(dict_test) + sum(len(v) for v in dict_test.values())

这里是recursion函数来查找嵌套字典的键的总数量…

 s=0 def recurse(v): if type(v)==type({}): for k in v.keys(): global s s+=1 recurse(v[k]) 

你可以尝试使用pandasDataFrame的:

 >>> import pandas as pd >>> data = {'1': {'2': 'a', '3': 'b'}, '4': {'5': 'c', '6': 'd'}, '7': {'5': 'x'}} >>> df = pd.DataFrame(data) >>> print (df.count().sum() + len(df.columns)) # 8 

pd.DataFrame(data)行会将你的字典转换成N×Mmatrix,其中N是“父”键的数量,M是唯一的子键的数量:

  1 4 7 2 a NaN NaN 3 b NaN NaN 5 NaN cx 6 NaN d NaN 

对于每个[行,列]你有一个值或NaN。 你只需要计算非NaN值,这将给你的子键的数量,并添加len(df.columns) ,即列的数量(即父键)。

recursion函数:

 def count_keys(some_dict): count = 0 for key in some_dict: if isinstance(some_dict[key], dict): count += count_keys(some_dict[key]) count += 1 return count 

len(dict)将返回字典中的键的数量,所以假设你知道它是如何嵌套的,并且所有的值都是字典:

 counter = len(outer_dict) for v in outer_dict.values : counter += len(v) 

你可以把它包装在列表理解中:

 counter = len(outer_dict) counter += sum([len(inner_dict) for inner_dict in outer_dict.values]) 

这可能是最pythonic。 您可以将其扩展为:

 counter = len(outer_dict) counter += sum([len(inner_dict) if isinstance(inner_dict, dict) else 0 for inner_dict in outer_dict.values]) 

但我倾向于认为这是相当难以理解的。

尝试这个,

 l = len(dict_test) for k in dict_test: l += len(dict_test[k])