首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >获取Python字典中所有键的数目。

获取Python字典中所有键的数目。
EN

Stack Overflow用户
提问于 2016-02-16 08:50:37
回答 10查看 30.4K关注 0票数 40

我有一本Python2.7的字典。

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

因此,在这个例子中,我需要所有键的数目为6:

代码语言:javascript
运行
复制
dict_test = {'key2': {'key_in3': 'value', 'key_in4': 'value'}, 'key1': {'key_in2': 'value', 'key_in1': 'value'}}

我知道我可以用for循环遍历每个键,但是我正在寻找一种更快的方法来实现这一点,因为我将拥有成千上万个键,而这样做是无效的:

代码语言:javascript
运行
复制
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())
EN

回答 10

Stack Overflow用户

回答已采纳

发布于 2016-02-16 09:07:36

保持简单

如果我们知道所有的值都是字典,并且不希望检查它们的任何值是否也是字典,那么它就是这样简单的:

代码语言:javascript
运行
复制
len(dict_test) + sum(len(v) for v in dict_test.itervalues())

对其进行一些改进,以便在计算值之前实际检查它们是否为字典:

代码语言:javascript
运行
复制
len(dict_test) + sum(len(v) for v in dict_test.itervalues() if isinstance(v, dict))

最后,如果您想做任意深度的操作,如下所示:

代码语言:javascript
运行
复制
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

在最后一个例子中,我们定义了一个将被递归调用的函数。给定一个值d,我们返回以下任一项:

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

使它更快

以上是一种简洁易懂的方法。我们可以更快地使用生成器:

代码语言:javascript
运行
复制
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))

这给我们带来了更多的性能:

代码语言:javascript
运行
复制
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
票数 34
EN

Stack Overflow用户

发布于 2016-02-16 08:59:00

怎么样

代码语言:javascript
运行
复制
n = sum([len(v)+1 for k, v in dict_test.items()])

你所做的是对所有的键k和值进行迭代,v是你的副词。您将获得这些字典的长度,并添加一个以包含用于索引子字典的键。

然后,对列表进行加和,以得到完整的键数。

编辑:

为了澄清,此片段仅适用于所要求的字典词典。不是字典的字典.

因此,不要将其用于嵌套示例:)

票数 9
EN

Stack Overflow用户

发布于 2016-02-16 09:05:01

作为一种更普遍的方法,您可以使用递归函数和生成器表达式:

代码语言:javascript
运行
复制
>>> def count_keys(dict_test):
...     return sum(1+count_keys(v) if isinstance(v,dict) else 1 for _,v in dict_test.iteritems())
... 

示例:

代码语言:javascript
运行
复制
>>> dict_test = {'a': {'c': '2', 'b': '1', 'e': {'f': {1: {5: 'a'}}}, 'd': '3'}}
>>> 
>>> count(dict_test)
8

注意:在python3.x中,使用dict.items()方法而不是iteritems()

一个具有可接受答案的基准,它表明这个函数比接受的答案更快:

代码语言:javascript
运行
复制
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'}}")

结果:

代码语言:javascript
运行
复制
1st:  4.65556812286
2nd :  4.09120802879
票数 9
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35427814

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档