获取 Python 字典中所有键的数量
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/35427814/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Get the number of all keys in a dictionary of dictionaries in Python
提问by ivan_bilan
I have a dictionary of dictionaries in Python 2.7.
我在 Python 2.7 中有一本字典。
I need to quickly count the number of all keys, including the keys within each of the dictionaries.
我需要快速计算所有键的数量,包括每个字典中的键。
So in this example I would need the number of all keys to be 6:
所以在这个例子中,我需要所有键的数量为 6:
dict_test = {'key2': {'key_in3': 'value', 'key_in4': 'value'}, 'key1': {'key_in2': 'value', 'key_in1': 'value'}}
I know I can iterate through each key with for loops, but I am looking for a quicker way to do this, since I will have thousands/millions of keys and doing this is just ineffective:
我知道我可以使用 for 循环遍历每个键,但我正在寻找一种更快的方法来做到这一点,因为我将拥有数千/数百万个键,而这样做是无效的:
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())
采纳答案by donkopotamus
Keeping it Simple
保持简单
If we know all the values are dictionaries, and do not wish to check that any of their values are also dictionaries, then it is as simple as:
如果我们知道所有的值都是字典,并且不希望检查它们的任何值是否也是字典,那么它很简单:
len(dict_test) + sum(len(v) for v in dict_test.itervalues())
Refining it a little, to actually check that the values are dictionaries before counting them:
稍微改进一下,在计算它们之前实际检查这些值是否是字典:
len(dict_test) + sum(len(v) for v in dict_test.itervalues() if isinstance(v, dict))
And finally, if you wish to do an arbitrary depth, something like the following:
最后,如果你想做一个任意的深度,像下面这样:
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
In this last case, we define a function that will be called recursively. Given a value d
, we return either:
在最后一种情况下,我们定义了一个将被递归调用的函数。给定一个 value d
,我们返回:
0
if that value is not a dictionary; or- the number of keys in the dictionary, plus the total of keys in all of our children.
0
如果该值不是字典;或者- 字典中键的数量,加上我们所有孩子的键总数。
Making it Faster
让它更快
The above is a succinct and easily understood approach. We can get a little faster using a generator:
以上是一种简洁易懂的方法。我们可以使用生成器加快速度:
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))
This gets us a bit more performance:
这让我们获得了更多的性能:
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
回答by MaxBenChrist
How about
怎么样
n = sum([len(v)+1 for k, v in dict_test.items()])
What you are doing is iterating over all keys k and values v. The values v are your subdictionaries. You get the length of those dictionaries and add one to include the key used to index the subdictionary.
您正在做的是迭代所有键 k 和值 v。值 v 是您的子字典。您获得这些词典的长度并添加一个以包含用于索引子词典的键。
Afterwards you sum over the list to get the complete number of keys.
之后,您对列表求和以获得完整的键数。
EDIT:
编辑:
To clarify, this snippet works only for dictionaries of dictionaries as asked. Not dictionaries of dictionaries of dictionaries...
So do not use it for nested example :)
澄清一下,这个片段仅适用于字典中的字典。不是字典的字典的字典......
所以不要将它用于嵌套示例:)
回答by Viacheslav Kondratiuk
Something like:
就像是:
print len(dict_test) + sum(len(v) for v in dict_test.values())
print len(dict_test) + sum(len(v) for v in dict_test.values())
回答by Dharmik
Try this,
尝试这个,
l = len(dict_test)
for k in dict_test:
l += len(dict_test[k])
回答by matino
You could try using pandas DataFrame for that:
您可以尝试使用 Pandas DataFrame:
>>> 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
The pd.DataFrame(data)
line will convert your dictionary to a N x M matrix, where N is number of "parent" keys and M is the number of unique children keys:
该pd.DataFrame(data)
行会将您的字典转换为 N x M 矩阵,其中 N 是“父”键的数量,M 是唯一子键的数量:
1 4 7
2 a NaN NaN
3 b NaN NaN
5 NaN c x
6 NaN d NaN
For each [row, column] you have a value or NaN. You just need to count the non NaN
values, which will give you the number of children keys and add len(df.columns)
, which stands for the number of columns (i.e. parent keys).
对于每个 [行,列],您都有一个值或 NaN。您只需要计算非NaN
值,这将为您提供子键的数量和 add len(df.columns)
,它代表列数(即父键)。
回答by Kasramvd
As a more general way you can use a recursion function and generator expression:
作为更通用的方法,您可以使用递归函数和生成器表达式:
>>> def count_keys(dict_test):
... return sum(1+count_keys(v) if isinstance(v,dict) else 1 for _,v in dict_test.iteritems())
...
Example:
例子:
>>> dict_test = {'a': {'c': '2', 'b': '1', 'e': {'f': {1: {5: 'a'}}}, 'd': '3'}}
>>>
>>> count(dict_test)
8
Note: In python 3.X use dict.items()
method instead of iteritems()
.
注意:在 python 3.X 中使用dict.items()
method 而不是iteritems()
.
A benchmark with accepted answer which shows that this function is faster than accepted answer:
具有接受答案的基准测试表明此函数比接受的答案更快:
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'}}")
result:
结果:
1st: 4.65556812286
2nd : 4.09120802879
回答by styvane
Using a generator function and the yield from
syntax new in Python 3.x. This will work for an arbitrary nested dictionary
使用生成器函数和yield from
Python 3.x 中的新语法。这将适用于任意嵌套字典
>>> 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
In Python 2.x you need a to do this:
在 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
回答by Konstantyn
recursive function:
递归函数:
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
回答by phil_20686
len(dict) will return the number of keys in a dictionary, so, assuming you know how nested it is and that all the values are dictionaries:
len(dict) 将返回字典中的键数,因此,假设您知道它是如何嵌套的并且所有值都是字典:
counter = len(outer_dict)
for v in outer_dict.values :
counter += len(v)
You can wrap this in a list comprehension :
您可以将其包装在列表理解中:
counter = len(outer_dict)
counter += sum([len(inner_dict) for inner_dict in outer_dict.values])
which is probably the most pythonic. You can extend it as :
这可能是最pythonic的。您可以将其扩展为:
counter = len(outer_dict)
counter += sum([len(inner_dict) if isinstance(inner_dict, dict) else 0 for inner_dict in outer_dict.values])
but I tend to think that this is fairly unreadable.
但我倾向于认为这是相当不可读的。
回答by Dharmik
Here is the recursive function to find the nested dictionaries' total number of keys...
这是查找嵌套字典键总数的递归函数...
s=0
def recurse(v):
if type(v)==type({}):
for k in v.keys():
global s
s+=1
recurse(v[k])