通过列表字典的递归函数
Recursive Function through dict of lists
给定这个数据结构
[{'name': 'Business Operations',
'team_edit': ['BusinessOperations'],
'team_view': ['Snaptest'],
'test_sub_subfolder': [
{'name': 'test_sub',
'team_edit': ['BusinessOperations', 'Freddy'],
'team_view': ['hugo']}],
'test_sub2_subfolder': [
{'name': 'test_sub2',
'test_sub_subfolder': [
{'name': 'test_sub_sub',
'team_edit': ['BusinessOperations', 'Freddy'],
'team_view': ['hugo']}]}]}]
我正在尝试编写一个递归函数,使我能够访问所有元素,本质上是将它们打印出来。嵌套结构可以是任意长度,但将始终遵循此格式。
我的第一次尝试是
def recurse_over_object(dict_obj):
for key, value in dict_obj.items():
if 'subfolder' in key:
for pair in recurse_over_object(value[0]):
print(key, *pair)
# yield (key, *pair)
else:
print(key, value)
# yield (key, value)
这里的问题是,当我沿着树向下走时,我要求值 subfolder
并沿着那条路线走,但在这个例子中,我有两个子文件夹在同一级别(test_sub
和 test_sub2
),我需要为它们获取值。
有谁知道有什么奇特的方法可以做到这一点吗?
如果需要,我绝对可以重组数据输入以使其更容易,例如,我的一个想法是将同一级别的子文件夹设置为 list
但后来我在一个递归函数中苦苦挣扎以遍历这些元素。
任何想法的帮助将不胜感激。
您可以在 if 'subfolder' in key:
下迭代调用 recurse_over_object
。所以喜欢:
def recurse_over_object(dict_obj):
for key, value in dict_obj.items():
if 'subfolder' in key:
for item in value:
recurse_over_object(item)
else:
print(key, value)
然后
for d in data:
recurse_over_object(d)
输出:
name Business Operations
team_edit ['BusinessOperations']
team_view ['Snaptest']
name test_sub
team_edit ['BusinessOperations', 'Freddy']
team_view ['hugo']
name test_sub2
name test_sub_sub
team_edit ['BusinessOperations', 'Freddy']
team_view ['hugo']
为了跟随您对 yield()
(以及 print
)的使用,这里是经过调整的代码,我认为它可以满足您的问题。请注意,最后的 x = list( ... )
语句旨在调用您的函数创建的生成器。
dataStructure = [
{'name': 'Business Operations',
'team_edit': ['BusinessOperations'],
'team_view': ['Snaptest'],
'test_sub_subfolder': [
{'name': 'test_sub',
'team_edit': ['BusinessOperations', 'Freddy'],
'team_view': ['hugo']}],
'test_sub2_subfolder': [
{'name': 'test_sub2',
'test_sub_subfolder': [
{'name': 'test_sub_sub',
'team_edit': ['BusinessOperations', 'Freddy'],
'team_view': ['hugo']}]}]}
]
def recurse_over_object(dict_obj):
for key, value in dict_obj.items():
if 'subfolder' in key:
'''
for pair in recurse_over_object(value[0]):
print(key, *pair)
yield (key, *pair)
'''
print(key, *list(recurse_over_object(value[0])))
yield(key, *list(recurse_over_object(value[0])))
else:
print(key, value)
yield (key, value)
x = list(recurse_over_object(dataStructure[0]))
输出:
name Business Operations
team_edit ['BusinessOperations']
team_view ['Snaptest']
name test_sub
team_edit ['BusinessOperations', 'Freddy']
team_view ['hugo']
test_sub_subfolder ('name', 'test_sub') ('team_edit', ['BusinessOperations', 'Freddy']) ('team_view', ['hugo'])
name test_sub
team_edit ['BusinessOperations', 'Freddy']
team_view ['hugo']
name test_sub2
name test_sub_sub
team_edit ['BusinessOperations', 'Freddy']
team_view ['hugo']
test_sub_subfolder ('name', 'test_sub_sub') ('team_edit', ['BusinessOperations', 'Freddy']) ('team_view', ['hugo'])
name test_sub_sub
team_edit ['BusinessOperations', 'Freddy']
team_view ['hugo']
test_sub2_subfolder ('name', 'test_sub2') ('test_sub_subfolder', ('name', 'test_sub_sub'), ('team_edit', ['BusinessOperations', 'Freddy']), ('team_view', ['hugo']))
name test_sub2
name test_sub_sub
team_edit ['BusinessOperations', 'Freddy']
team_view ['hugo']
test_sub_subfolder ('name', 'test_sub_sub') ('team_edit', ['BusinessOperations', 'Freddy']) ('team_view', ['hugo'])
name test_sub_sub
team_edit ['BusinessOperations', 'Freddy']
team_view ['hugo']
您有一个包含列表、字典和字符串的嵌套结构。递归函数可以测试它来决定如何处理元素:
def get_branches(x, acc=()):
if isinstance(x, dict):
for k,v in x.items():
yield from get_branches(v, acc+(k,))
elif isinstance(x, list):
for k in x:
yield from get_branches(k, acc)
else:
yield acc + (x,)
x = [{'name': 'Business Operations',
'team_edit': ['BusinessOperations'],
'team_view': ['Snaptest'],
'test_sub_subfolder': [
{'name': 'test_sub',
'team_edit': ['BusinessOperations', 'Freddy'],
'team_view': ['hugo']}],
'test_sub2_subfolder': [
{'name': 'test_sub2',
'test_sub_subfolder': [
{'name': 'test_sub_sub',
'team_edit': ['BusinessOperations', 'Freddy'],
'team_view': ['hugo']}]}]}]
print(list( get_branches(x) ))
输出:
[('name', 'Business Operations'),
('team_edit', 'BusinessOperations'),
('team_view', 'Snaptest'),
('test_sub_subfolder', 'name', 'test_sub'),
('test_sub_subfolder', 'team_edit', 'BusinessOperations'),
('test_sub_subfolder', 'team_edit', 'Freddy'),
('test_sub_subfolder', 'team_view', 'hugo'),
('test_sub2_subfolder', 'name', 'test_sub2'),
('test_sub2_subfolder', 'test_sub_subfolder', 'name', 'test_sub_sub'),
('test_sub2_subfolder', 'test_sub_subfolder', 'team_edit', 'BusinessOperations'),
('test_sub2_subfolder', 'test_sub_subfolder', 'team_edit', 'Freddy'),
('test_sub2_subfolder', 'test_sub_subfolder', 'team_view', 'hugo')
]
给定这个数据结构
[{'name': 'Business Operations',
'team_edit': ['BusinessOperations'],
'team_view': ['Snaptest'],
'test_sub_subfolder': [
{'name': 'test_sub',
'team_edit': ['BusinessOperations', 'Freddy'],
'team_view': ['hugo']}],
'test_sub2_subfolder': [
{'name': 'test_sub2',
'test_sub_subfolder': [
{'name': 'test_sub_sub',
'team_edit': ['BusinessOperations', 'Freddy'],
'team_view': ['hugo']}]}]}]
我正在尝试编写一个递归函数,使我能够访问所有元素,本质上是将它们打印出来。嵌套结构可以是任意长度,但将始终遵循此格式。
我的第一次尝试是
def recurse_over_object(dict_obj):
for key, value in dict_obj.items():
if 'subfolder' in key:
for pair in recurse_over_object(value[0]):
print(key, *pair)
# yield (key, *pair)
else:
print(key, value)
# yield (key, value)
这里的问题是,当我沿着树向下走时,我要求值 subfolder
并沿着那条路线走,但在这个例子中,我有两个子文件夹在同一级别(test_sub
和 test_sub2
),我需要为它们获取值。
有谁知道有什么奇特的方法可以做到这一点吗?
如果需要,我绝对可以重组数据输入以使其更容易,例如,我的一个想法是将同一级别的子文件夹设置为 list
但后来我在一个递归函数中苦苦挣扎以遍历这些元素。
任何想法的帮助将不胜感激。
您可以在 if 'subfolder' in key:
下迭代调用 recurse_over_object
。所以喜欢:
def recurse_over_object(dict_obj):
for key, value in dict_obj.items():
if 'subfolder' in key:
for item in value:
recurse_over_object(item)
else:
print(key, value)
然后
for d in data:
recurse_over_object(d)
输出:
name Business Operations
team_edit ['BusinessOperations']
team_view ['Snaptest']
name test_sub
team_edit ['BusinessOperations', 'Freddy']
team_view ['hugo']
name test_sub2
name test_sub_sub
team_edit ['BusinessOperations', 'Freddy']
team_view ['hugo']
为了跟随您对 yield()
(以及 print
)的使用,这里是经过调整的代码,我认为它可以满足您的问题。请注意,最后的 x = list( ... )
语句旨在调用您的函数创建的生成器。
dataStructure = [
{'name': 'Business Operations',
'team_edit': ['BusinessOperations'],
'team_view': ['Snaptest'],
'test_sub_subfolder': [
{'name': 'test_sub',
'team_edit': ['BusinessOperations', 'Freddy'],
'team_view': ['hugo']}],
'test_sub2_subfolder': [
{'name': 'test_sub2',
'test_sub_subfolder': [
{'name': 'test_sub_sub',
'team_edit': ['BusinessOperations', 'Freddy'],
'team_view': ['hugo']}]}]}
]
def recurse_over_object(dict_obj):
for key, value in dict_obj.items():
if 'subfolder' in key:
'''
for pair in recurse_over_object(value[0]):
print(key, *pair)
yield (key, *pair)
'''
print(key, *list(recurse_over_object(value[0])))
yield(key, *list(recurse_over_object(value[0])))
else:
print(key, value)
yield (key, value)
x = list(recurse_over_object(dataStructure[0]))
输出:
name Business Operations
team_edit ['BusinessOperations']
team_view ['Snaptest']
name test_sub
team_edit ['BusinessOperations', 'Freddy']
team_view ['hugo']
test_sub_subfolder ('name', 'test_sub') ('team_edit', ['BusinessOperations', 'Freddy']) ('team_view', ['hugo'])
name test_sub
team_edit ['BusinessOperations', 'Freddy']
team_view ['hugo']
name test_sub2
name test_sub_sub
team_edit ['BusinessOperations', 'Freddy']
team_view ['hugo']
test_sub_subfolder ('name', 'test_sub_sub') ('team_edit', ['BusinessOperations', 'Freddy']) ('team_view', ['hugo'])
name test_sub_sub
team_edit ['BusinessOperations', 'Freddy']
team_view ['hugo']
test_sub2_subfolder ('name', 'test_sub2') ('test_sub_subfolder', ('name', 'test_sub_sub'), ('team_edit', ['BusinessOperations', 'Freddy']), ('team_view', ['hugo']))
name test_sub2
name test_sub_sub
team_edit ['BusinessOperations', 'Freddy']
team_view ['hugo']
test_sub_subfolder ('name', 'test_sub_sub') ('team_edit', ['BusinessOperations', 'Freddy']) ('team_view', ['hugo'])
name test_sub_sub
team_edit ['BusinessOperations', 'Freddy']
team_view ['hugo']
您有一个包含列表、字典和字符串的嵌套结构。递归函数可以测试它来决定如何处理元素:
def get_branches(x, acc=()):
if isinstance(x, dict):
for k,v in x.items():
yield from get_branches(v, acc+(k,))
elif isinstance(x, list):
for k in x:
yield from get_branches(k, acc)
else:
yield acc + (x,)
x = [{'name': 'Business Operations',
'team_edit': ['BusinessOperations'],
'team_view': ['Snaptest'],
'test_sub_subfolder': [
{'name': 'test_sub',
'team_edit': ['BusinessOperations', 'Freddy'],
'team_view': ['hugo']}],
'test_sub2_subfolder': [
{'name': 'test_sub2',
'test_sub_subfolder': [
{'name': 'test_sub_sub',
'team_edit': ['BusinessOperations', 'Freddy'],
'team_view': ['hugo']}]}]}]
print(list( get_branches(x) ))
输出:
[('name', 'Business Operations'),
('team_edit', 'BusinessOperations'),
('team_view', 'Snaptest'),
('test_sub_subfolder', 'name', 'test_sub'),
('test_sub_subfolder', 'team_edit', 'BusinessOperations'),
('test_sub_subfolder', 'team_edit', 'Freddy'),
('test_sub_subfolder', 'team_view', 'hugo'),
('test_sub2_subfolder', 'name', 'test_sub2'),
('test_sub2_subfolder', 'test_sub_subfolder', 'name', 'test_sub_sub'),
('test_sub2_subfolder', 'test_sub_subfolder', 'team_edit', 'BusinessOperations'),
('test_sub2_subfolder', 'test_sub_subfolder', 'team_edit', 'Freddy'),
('test_sub2_subfolder', 'test_sub_subfolder', 'team_view', 'hugo')
]