[英]Get a list of all keys in nested dictionary
I want to get a list of all keys in a nested dictionary that contains lists and dictionaries.我想获取包含列表和字典的嵌套字典中所有键的列表。
I currently have this code, but it seems to be missing adding some keys to the list and also duplicate adds some keys.我目前有这段代码,但似乎缺少向列表中添加一些键,并且重复添加了一些键。
keys_list = []
def get_keys(d_or_l, keys_list):
if isinstance(d_or_l, dict):
for k, v in iter(sorted(d_or_l.iteritems())):
if isinstance(v, list):
get_keys(v, keys_list)
elif isinstance(v, dict):
get_keys(v, keys_list)
else:
keys_list.append(k)
elif isinstance(d_or_l, list):
for i in d_or_l:
if isinstance(i, list):
get_keys(i, keys_list)
elif isinstance(i, dict):
get_keys(i, keys_list)
else:
print "** Skipping item of type: {}".format(type(d_or_l))
return keys_list
This should do the job:这应该可以完成这项工作:
def get_keys(dl, keys_list):
if isinstance(dl, dict):
keys_list += dl.keys()
map(lambda x: get_keys(x, keys_list), dl.values())
elif isinstance(dl, list):
map(lambda x: get_keys(x, keys_list), dl)
To avoid duplicates you can use set, eg:为避免重复,您可以使用 set,例如:
keys_list = list( set( keys_list ) )
Example test case:示例测试用例:
keys_list = []
d = {1: 2, 3: 4, 5: [{7: {9: 1}}]}
get_keys(d, keys_list)
print keys_list
>>>> [1, 3, 5, 7, 9]
As it stands, your code ignores keys that lead to list
or dict
values.就目前而言,您的代码会忽略导致
list
或dict
值的键。 Remove the else
block in your first for
loop, you want to add the key no matter what the value is.删除第一个
for
循环中的else
块,无论值是什么,您都希望添加键。
keys_list = []
def get_keys(d_or_l, keys_list):
if isinstance(d_or_l, dict):
for k, v in iter(sorted(d_or_l.iteritems())):
if isinstance(v, list):
get_keys(v, keys_list)
elif isinstance(v, dict):
get_keys(v, keys_list)
keys_list.append(k) # Altered line
elif isinstance(d_or_l, list):
for i in d_or_l:
if isinstance(i, list):
get_keys(i, keys_list)
elif isinstance(i, dict):
get_keys(i, keys_list)
else:
print "** Skipping item of type: {}".format(type(d_or_l))
return keys_list
get_keys({1: 2, 3: 4, 5: [{7: {9: 1}}]}, keys_list)
returns [1, 3, 9, 7, 5]
get_keys({1: 2, 3: 4, 5: [{7: {9: 1}}]}, keys_list)
返回[1, 3, 9, 7, 5]
To avoid duplication, you could use a set
datatype instead of a list
.为避免重复,您可以使用
set
数据类型而不是list
。
Updating @MackM's response to Python 3 as dict.iteritems
has been deprecated (and I prefer to use f-strings over the .format{}
styling):更新@MackM 对 Python 3 的响应,因为
dict.iteritems
已被弃用(我更喜欢在.format{}
样式上使用 f 字符串):
keys_list = []
def get_keys(d_or_l, keys_list):
if isinstance(d_or_l, dict):
for k, v in iter(sorted(d_or_l.items())): # Altered line to update deprecated method
if isinstance(v, list):
get_keys(v, keys_list)
elif isinstance(v, dict):
get_keys(v, keys_list)
keys_list.append(k)
elif isinstance(d_or_l, list):
for i in d_or_l:
if isinstance(i, list):
get_keys(i, keys_list)
elif isinstance(i, dict):
get_keys(i, keys_list)
else:
print(f'** Skipping item of type: {type(d_or_l)}') # Altered line to use f-strings
return keys_list
unique_keys = list(set(get_keys(my_json_dict, keys_list))) # Added line as example use case
Here is a simple solution:这是一个简单的解决方案:
def get_nested_keys(d, keys):
for k, v in d.items():
if isinstance(v, dict):
get_nested_keys(v, keys)
else:
keys.append(k)
keys_list = []
get_nested_keys(test_listing, keys_list)
print(keys_list)
If you want to know the hierarchy of the keys as well, you can modify the function like so:如果您还想知道键的层次结构,可以像这样修改函数:
def get_nested_keys(d, keys, prefix):
for k, v in d.items():
if isinstance(v, dict):
get_nested_keys(v, keys, f'{prefix}:{k}')
else:
keys.append(f'{prefix}:{k}')
I would extend @pm007 answer by a python 2 & 3 friendly version:我将通过 python 2 & 3 友好版本扩展@pm007 答案:
def get_keys(dl, keys=None):
keys = keys or []
if isinstance(dl, dict):
keys += dl.keys()
list(map(lambda x: get_keys(x, keys), dl.values()))
elif isinstance(dl, list):
list(map(lambda x: get_keys(x, keys), dl))
return list(set(keys))
d = {1: 2, 3: 4, 5: {7: {1: 1}}}
get_keys(d)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.