Python ';非类型';递归解析dict时不可iterable吗?
使用此功能:Python ';非类型';递归解析dict时不可iterable吗?,python,dictionary,recursion,data-structures,Python,Dictionary,Recursion,Data Structures,使用此功能: def extract_flat_branch(nested_dict, c = []): for i in ['left', 'op', 'right', 'func', 'value', 'args', 'ctx', 'body', 'comparators', 'ops', 'test', 'orelse', 'targets', 'slice']: if i in nested_dict: if
def extract_flat_branch(nested_dict, c = []):
for i in ['left', 'op', 'right', 'func', 'value', 'args',
'ctx', 'body', 'comparators', 'ops', 'test', 'orelse', 'targets', 'slice']:
if i in nested_dict:
if isinstance(nested_dict[i], list):
for b in nested_dict[i]:
yield from extract_flat_branch(b, c+[nested_dict['_type']])
else:
yield from extract_flat_branch(nested_dict[i], c+[nested_dict['_type']])
lis = [c+[nested_dict['_type'], i] for i in filter(None, [nested_dict.get(j) for j in ['n', 'id']])]
yield from lis if lis else [c+[nested_dict['_type']]] if len(nested_dict) == 1 else []
我正在遍历并提取这棵树的分支(表示为this dictionary()),它是一个字符串列表,其中树的所有分支都是一个平面列表的元素。然而,出于某种原因,当我这样做时:
在:
而不是获得类似的输出:
[[node_1, node_2, .., node_n],[node_1, node_2, .., node_n],...,[node_1, node_2, .., node_n]]
我得到:
TypeError: argument of type 'NoneType' is not iterable
基于此,我认为问题在于我正在使用的.get(j)
。但是,如果我在['n',id']]中嵌套了[code>dict.get(j)或{}for j我仍然会得到相同的TypeError
。你知道如何解决这个问题并获得树的分支的平面列表吗
这是完整跟踪:
TypeError Traceback (most recent call last)
<ipython-input-4-51bfd7bbf4e4> in <module>
1 for i,j in enumerate(a_lis):
2 print(i)
----> 3 print(list(extract_flat_branch(j)))
~/dir/util.py in extract_flat_branch(nested_dict, c)
38 if isinstance(nested_dict[i], list):
39 for b in nested_dict[i]:
---> 40 yield from extract_flat_branch(b, c+[nested_dict['_type']])
41 else:
42 yield from extract_flat_branch(nested_dict[i], c+[nested_dict['_type']])
~/dir/util.py in extract_flat_branch(nested_dict, c)
38 if isinstance(nested_dict[i], list):
39 for b in nested_dict[i]:
---> 40 yield from extract_flat_branch(b, c+[nested_dict['_type']])
41 else:
42 yield from extract_flat_branch(nested_dict[i], c+[nested_dict['_type']])
~/dir/util.py in extract_flat_branch(nested_dict, c)
40 yield from extract_flat_branch(b, c+[nested_dict['_type']])
41 else:
---> 42 yield from extract_flat_branch(nested_dict[i], c+[nested_dict['_type']])
43 lis = [c+[nested_dict['_type'], i] for i in filter(None, [nested_dict.get(j) for j in ['n', 'id']])]
44 yield from lis if lis else [c+[nested_dict['_type']]] if len(nested_dict) == 1 else []
~/dir/util.py in extract_flat_branch(nested_dict, c)
38 if isinstance(nested_dict[i], list):
39 for b in nested_dict[i]:
---> 40 yield from extract_flat_branch(b, c+[nested_dict['_type']])
41 else:
42 yield from extract_flat_branch(nested_dict[i], c+[nested_dict['_type']])
~/dir/util.py in extract_flat_branch(nested_dict, c)
40 yield from extract_flat_branch(b, c+[nested_dict['_type']])
41 else:
---> 42 yield from extract_flat_branch(nested_dict[i], c+[nested_dict['_type']])
43 lis = [c+[nested_dict['_type'], i] for i in filter(None, [nested_dict.get(j) for j in ['n', 'id']])]
44 yield from lis if lis else [c+[nested_dict['_type']]] if len(nested_dict) == 1 else []
~/dir/util.py in extract_flat_branch(nested_dict, c)
35 for i in ['left', 'op', 'right', 'func', 'value', 'args',
36 'ctx', 'body', 'comparators', 'ops', 'test', 'orelse', 'targets', 'slice']:
---> 37 if i in nested_dict:
38 if isinstance(nested_dict[i], list):
39 for b in nested_dict[i]:
TypeError: argument of type 'NoneType' is not iterable
TypeError回溯(最近一次调用)
在里面
1表示枚举中的i,j(a_lis):
2印刷品(一)
---->3打印(列表(摘录平面分支(j)))
提取平面分支中的~/dir/util.py(嵌套目录,c)
38如果存在(嵌套目录[i],列表):
39对于嵌套目录[i]中的b:
--->40抽提扁平分支的产量(b,c+[嵌套目录[''类型]]
41其他:
42提取扁平分支的产量(嵌套式目录[i],c+[嵌套式目录[''类型]]
提取平面分支中的~/dir/util.py(嵌套目录,c)
38如果存在(嵌套目录[i],列表):
39对于嵌套目录[i]中的b:
--->40抽提扁平分支的产量(b,c+[嵌套目录[''类型]]
41其他:
42提取扁平分支的产量(嵌套式目录[i],c+[嵌套式目录[''类型]]
提取平面分支中的~/dir/util.py(嵌套目录,c)
40抽提扁平分支的产量(b,c+[嵌套目录[''类型]]
41其他:
--->42提取扁平分支的产量(嵌套式目录[i],c+[嵌套式目录[''类型]]
43 lis=[c+[nested_dict[''u type'],i]表示过滤器中的i(无[nested_dict.get(j)表示过滤器中的j['n','id'])]
44如果lis else[c+[nested_-dict[''U-type']]如果len(nested_-dict)=1 else[]
提取平面分支中的~/dir/util.py(嵌套目录,c)
38如果存在(嵌套目录[i],列表):
39对于嵌套目录[i]中的b:
--->40抽提扁平分支的产量(b,c+[嵌套目录[''类型]]
41其他:
42提取扁平分支的产量(嵌套式目录[i],c+[嵌套式目录[''类型]]
提取平面分支中的~/dir/util.py(嵌套目录,c)
40抽提扁平分支的产量(b,c+[嵌套目录[''类型]]
41其他:
--->42提取扁平分支的产量(嵌套式目录[i],c+[嵌套式目录[''类型]]
43 lis=[c+[nested_dict[''u type'],i]表示过滤器中的i(无[nested_dict.get(j)表示过滤器中的j['n','id'])]
44如果lis else[c+[nested_-dict[''U-type']]如果len(nested_-dict)=1 else[]
提取平面分支中的~/dir/util.py(嵌套目录,c)
35对于['left','op','right','func','value','args'中的i,
36“ctx”、“主体”、“比较器”、“ops”、“测试”、“orelse”、“目标”、“切片”]:
--->37如果我在嵌套目录中:
38如果存在(嵌套目录[i],列表):
39对于嵌套目录[i]中的b:
TypeError:类型为“NoneType”的参数不可编辑
引发NoneType
错误,因为在您的数据中有一个特定的“value”
键,该键被散列到相应的None
<代码>“值”是函数签名正下方的键列表中的目标键,当前逻辑尝试检查函数输入嵌套\u dict
中是否存在任何此类键。对于具有None
值的目标键,不清楚您想要的输出是什么,但一个简单的解决方法是检查并忽略这种情况:
def extract_flat_branch(nested_dict, c = []):
for i in ['left', 'op', 'right', 'func', 'value', 'args', 'ctx', 'body', 'comparators', 'ops', 'test', 'orelse', 'targets', 'slice', 'n', 'id']:
if i in nested_dict:
if isinstance(nested_dict[i], list):
for b in nested_dict[i]:
yield from extract_flat_branch(b, c+[nested_dict['_type']])
elif isinstance(nested_dict[i], dict): #simple check here
yield from extract_flat_branch(nested_dict[i], c+[nested_dict['_type']])
else:
yield c+[nested_dict[i]]
print(list(extract_flat_branch(data)))
输出:
[['FunctionDef', 'Assign', 'Call', 'Name', 'Load'], ['FunctionDef', 'Assign', 'Call', 'Name', 'list'], ['FunctionDef', 'Assign', 'Call', 'Name', 'Load'], ['FunctionDef', 'Assign', 'Call', 'Name', 'items'], ['FunctionDef', 'Assign', 'Name', 'Store'], ['FunctionDef', 'Assign', 'Name', 'items'], ['FunctionDef', 'Assign', 'Call', 'Name', 'Load'], ['FunctionDef', 'Assign', 'Call', 'Name', 'next_power_of_two'], ['FunctionDef', 'Assign', 'Call', 'Call', 'Name', 'Load'], ['FunctionDef', 'Assign', 'Call', 'Call', 'Name', 'int'], ['FunctionDef', 'Assign', 'Call', 'Call', 'BinOp', 'Num', 1.2], ['FunctionDef', 'Assign', 'Call', 'Call', 'BinOp', 'Mult'], ['FunctionDef', 'Assign', 'Call', 'Call', 'BinOp', 'Call', 'Name', 'Load'], ['FunctionDef', 'Assign', 'Call', 'Call', 'BinOp', 'Call', 'Name', 'len'], ['FunctionDef', 'Assign', 'Call', 'Call', 'BinOp', 'Call', 'Name', 'Load'], ['FunctionDef', 'Assign', 'Call', 'Call', 'BinOp', 'Call', 'Name', 'items'], ['FunctionDef', 'Assign', 'Name', 'Store'], ['FunctionDef', 'Assign', 'Name', 'size'], ['FunctionDef', 'Assign', 'BinOp', 'List', 'Load'], ['FunctionDef', 'Assign', 'BinOp', 'Mult'], ['FunctionDef', 'Assign', 'BinOp', 'Name', 'Load'], ['FunctionDef', 'Assign', 'BinOp', 'Name', 'size'], ['FunctionDef', 'Assign', 'Name', 'Store'], ['FunctionDef', 'Assign', 'Name', 'table'], ['FunctionDef', 'For', 'Assign', 'BinOp', 'Call', 'Name', 'Load'], ['FunctionDef', 'For', 'Assign', 'BinOp', 'Call', 'Name', 'hash_function'], ['FunctionDef', 'For', 'Assign', 'BinOp', 'Call', 'Name', 'Load'], ['FunctionDef', 'For', 'Assign', 'BinOp', 'Call', 'Name', 'i'], ['FunctionDef', 'For', 'Assign', 'BinOp', 'Mod'], ['FunctionDef', 'For', 'Assign', 'BinOp', 'Name', 'Load'], ['FunctionDef', 'For', 'Assign', 'BinOp', 'Name', 'size'], ['FunctionDef', 'For', 'Assign', 'Name', 'Store'], ['FunctionDef', 'For', 'Assign', 'Name', 'h'], ['FunctionDef', 'For', 'Assign', 'Name', 'Store'], ['FunctionDef', 'For', 'Assign', 'Name', 's'], ['FunctionDef', 'For', 'While', 'AugAssign', 'Add'], ['FunctionDef', 'For', 'While', 'AugAssign', 'Num', 1], ['FunctionDef', 'For', 'While', 'Assign', 'BinOp', 'BinOp', 'Name', 'Load'], ['FunctionDef', 'For', 'While', 'Assign', 'BinOp', 'BinOp', 'Name', 'h'], ['FunctionDef', 'For', 'While', 'Assign', 'BinOp', 'BinOp', 'Add'], ['FunctionDef', 'For', 'While', 'Assign', 'BinOp', 'BinOp', 'Name', 'Load'], ['FunctionDef', 'For', 'While', 'Assign', 'BinOp', 'BinOp', 'Name', 's'], ['FunctionDef', 'For', 'While', 'Assign', 'BinOp', 'Mod'], ['FunctionDef', 'For', 'While', 'Assign', 'BinOp', 'Name', 'Load'], ['FunctionDef', 'For', 'While', 'Assign', 'BinOp', 'Name', 'size'], ['FunctionDef', 'For', 'While', 'Assign', 'Name', 'Store'], ['FunctionDef', 'For', 'While', 'Assign', 'Name', 'h'], ['FunctionDef', 'For', 'While', 'Compare', 'Subscript', 'Name', 'Load'], ['FunctionDef', 'For', 'While', 'Compare', 'Subscript', 'Name', 'table'], ['FunctionDef', 'For', 'While', 'Compare', 'Subscript', 'Load'], ['FunctionDef', 'For', 'While', 'Compare', 'Subscript', 'Index', 'Name', 'Load'], ['FunctionDef', 'For', 'While', 'Compare', 'Subscript', 'Index', 'Name', 'h'], ['FunctionDef', 'For', 'While', 'Compare', None], ['FunctionDef', 'For', 'While', 'Compare', 'IsNot'], ['FunctionDef', 'For', 'Assign', 'Name', 'Load'], ['FunctionDef', 'For', 'Assign', 'Name', 'i'], ['FunctionDef', 'For', 'Assign', 'Subscript', 'Name', 'Load'], ['FunctionDef', 'For', 'Assign', 'Subscript', 'Name', 'table'], ['FunctionDef', 'For', 'Assign', 'Subscript', 'Store'], ['FunctionDef', 'For', 'Assign', 'Subscript', 'Index', 'Name', 'Load'], ['FunctionDef', 'For', 'Assign', 'Subscript', 'Index', 'Name', 'h'], ['FunctionDef', 'Return', 'Name', 'Load'], ['FunctionDef', 'Return', 'Name', 'table']]
[['FunctionDef'], ['args', 'arguments'], ['args', 'args', 'arg'], ['args', 'args', None], ['args', 'args', 'self'], ['body', 'Expr'], ['body', 'value', 'Str'], ['body', 'value', 'Like items(), but with all lowercase keys.'], ['body', 'Return'], ['body', 'value', 'GeneratorExp']]
更新的解决方案:
def extract_flat_branch(nested_dict, c = []):
targets = {'left', 'op', 'right', 'func', 'value', 'args', 'ctx', 'body', 'comparators', 'ops', 'test', 'orelse', 'targets', 'slice', 'n', 'id', 'slice', 'annotation', 'arg', 'elts', 's', '_type'}
for a, b in nested_dict.items():
if a in targets:
if isinstance(b, dict):
yield from extract_flat_branch(b, c+[a])
elif isinstance(b, list):
for i in b:
yield from extract_flat_branch(i, c+[a])
else:
yield c+[b]
print(list(extract_flat_branch(data)))
输出:
[['FunctionDef', 'Assign', 'Call', 'Name', 'Load'], ['FunctionDef', 'Assign', 'Call', 'Name', 'list'], ['FunctionDef', 'Assign', 'Call', 'Name', 'Load'], ['FunctionDef', 'Assign', 'Call', 'Name', 'items'], ['FunctionDef', 'Assign', 'Name', 'Store'], ['FunctionDef', 'Assign', 'Name', 'items'], ['FunctionDef', 'Assign', 'Call', 'Name', 'Load'], ['FunctionDef', 'Assign', 'Call', 'Name', 'next_power_of_two'], ['FunctionDef', 'Assign', 'Call', 'Call', 'Name', 'Load'], ['FunctionDef', 'Assign', 'Call', 'Call', 'Name', 'int'], ['FunctionDef', 'Assign', 'Call', 'Call', 'BinOp', 'Num', 1.2], ['FunctionDef', 'Assign', 'Call', 'Call', 'BinOp', 'Mult'], ['FunctionDef', 'Assign', 'Call', 'Call', 'BinOp', 'Call', 'Name', 'Load'], ['FunctionDef', 'Assign', 'Call', 'Call', 'BinOp', 'Call', 'Name', 'len'], ['FunctionDef', 'Assign', 'Call', 'Call', 'BinOp', 'Call', 'Name', 'Load'], ['FunctionDef', 'Assign', 'Call', 'Call', 'BinOp', 'Call', 'Name', 'items'], ['FunctionDef', 'Assign', 'Name', 'Store'], ['FunctionDef', 'Assign', 'Name', 'size'], ['FunctionDef', 'Assign', 'BinOp', 'List', 'Load'], ['FunctionDef', 'Assign', 'BinOp', 'Mult'], ['FunctionDef', 'Assign', 'BinOp', 'Name', 'Load'], ['FunctionDef', 'Assign', 'BinOp', 'Name', 'size'], ['FunctionDef', 'Assign', 'Name', 'Store'], ['FunctionDef', 'Assign', 'Name', 'table'], ['FunctionDef', 'For', 'Assign', 'BinOp', 'Call', 'Name', 'Load'], ['FunctionDef', 'For', 'Assign', 'BinOp', 'Call', 'Name', 'hash_function'], ['FunctionDef', 'For', 'Assign', 'BinOp', 'Call', 'Name', 'Load'], ['FunctionDef', 'For', 'Assign', 'BinOp', 'Call', 'Name', 'i'], ['FunctionDef', 'For', 'Assign', 'BinOp', 'Mod'], ['FunctionDef', 'For', 'Assign', 'BinOp', 'Name', 'Load'], ['FunctionDef', 'For', 'Assign', 'BinOp', 'Name', 'size'], ['FunctionDef', 'For', 'Assign', 'Name', 'Store'], ['FunctionDef', 'For', 'Assign', 'Name', 'h'], ['FunctionDef', 'For', 'Assign', 'Name', 'Store'], ['FunctionDef', 'For', 'Assign', 'Name', 's'], ['FunctionDef', 'For', 'While', 'AugAssign', 'Add'], ['FunctionDef', 'For', 'While', 'AugAssign', 'Num', 1], ['FunctionDef', 'For', 'While', 'Assign', 'BinOp', 'BinOp', 'Name', 'Load'], ['FunctionDef', 'For', 'While', 'Assign', 'BinOp', 'BinOp', 'Name', 'h'], ['FunctionDef', 'For', 'While', 'Assign', 'BinOp', 'BinOp', 'Add'], ['FunctionDef', 'For', 'While', 'Assign', 'BinOp', 'BinOp', 'Name', 'Load'], ['FunctionDef', 'For', 'While', 'Assign', 'BinOp', 'BinOp', 'Name', 's'], ['FunctionDef', 'For', 'While', 'Assign', 'BinOp', 'Mod'], ['FunctionDef', 'For', 'While', 'Assign', 'BinOp', 'Name', 'Load'], ['FunctionDef', 'For', 'While', 'Assign', 'BinOp', 'Name', 'size'], ['FunctionDef', 'For', 'While', 'Assign', 'Name', 'Store'], ['FunctionDef', 'For', 'While', 'Assign', 'Name', 'h'], ['FunctionDef', 'For', 'While', 'Compare', 'Subscript', 'Name', 'Load'], ['FunctionDef', 'For', 'While', 'Compare', 'Subscript', 'Name', 'table'], ['FunctionDef', 'For', 'While', 'Compare', 'Subscript', 'Load'], ['FunctionDef', 'For', 'While', 'Compare', 'Subscript', 'Index', 'Name', 'Load'], ['FunctionDef', 'For', 'While', 'Compare', 'Subscript', 'Index', 'Name', 'h'], ['FunctionDef', 'For', 'While', 'Compare', None], ['FunctionDef', 'For', 'While', 'Compare', 'IsNot'], ['FunctionDef', 'For', 'Assign', 'Name', 'Load'], ['FunctionDef', 'For', 'Assign', 'Name', 'i'], ['FunctionDef', 'For', 'Assign', 'Subscript', 'Name', 'Load'], ['FunctionDef', 'For', 'Assign', 'Subscript', 'Name', 'table'], ['FunctionDef', 'For', 'Assign', 'Subscript', 'Store'], ['FunctionDef', 'For', 'Assign', 'Subscript', 'Index', 'Name', 'Load'], ['FunctionDef', 'For', 'Assign', 'Subscript', 'Index', 'Name', 'h'], ['FunctionDef', 'Return', 'Name', 'Load'], ['FunctionDef', 'Return', 'Name', 'table']]
[['FunctionDef'], ['args', 'arguments'], ['args', 'args', 'arg'], ['args', 'args', None], ['args', 'args', 'self'], ['body', 'Expr'], ['body', 'value', 'Str'], ['body', 'value', 'Like items(), but with all lowercase keys.'], ['body', 'Return'], ['body', 'value', 'GeneratorExp']]
@00,我添加了完整的跟踪,谢谢help@JDo很乐意帮忙@JDo如果您首先有一个
None
,然后是一个bool
而不是iterable,那么您可能应该检查nested_dict[i]
是否是iterable(但要注意字符串)。再者,考虑到这种情况更为频繁,可能您的代码逻辑(或您的输入,但可能性较小)需要更全面的检查。@JDo请参阅我最近的编辑。因为目标键似乎可以存储任何类型的值,所以我认为最好的方法就是检查nested_dict[I]
是否是一个iterable.@JDo我不确定输出是否是您现在正在寻找的,但在本例中,我添加了一行yield c+[nested_dict[I]]
在目标键的值不可编辑的情况下生成输出行。请看我最近的编辑。@JDo没问题,让我看看