[英]Recursively flatten an object
I have the following object: 我有以下对象:
d={
'CollectionTitleIDs': {
'852070#TVEpisode': '12',
'852063#TVEpisode': '4',
'852067#TVEpisode': '9'
},
'ReleaseYear': '2005',
'TVSeriesID': '5638#TVSeries'
}
I would like to flatten it to get the following output: 我想展平它以获得以下输出:
{
'CollectionTitleIDs': [
{"_Key": "852070#TVEpisode", "Value": "12"},
{"_Key": "852063#TVEpisode", "Value": "4"},
{"_Key": "852067#TVEpisode", "Value": "9"}
]
'ReleaseYear': '2005',
'TVSeriesID': '5638#TVSeries'
}
In other words, if the value of the key is a dict, to push the keys of that dict to a "_Key" field and the value of that to a "Value" field. 换句话说,如果键的值是字典,则将该键的键推到“ _Key”字段,并将键的值推到“ Value”字段。
I've been having difficulty with the recursion. 我一直在递归有困难。 And currently I have something like this:
目前我有这样的事情:
What I currently have is: 我目前拥有的是:
def flatten_obj(obj, FLAT_OBJ=None):
if FLAT_OBJ is None: FLAT_OBJ = OrderedDict()
if isinstance(obj, list):
return [flatten_obj(l, FLAT_OBJ=FLAT_OBJ) for l in obj]
elif not isinstance(obj, dict):
return obj
else:
for key in list(obj.keys()):
val = get_sub_object_from_path(obj, key)
if isinstance(val, dict):
FLAT_OBJ[key] = [{'_Key': subkey, 'Value': flatten_obj(subval)} for subkey, subval in val.items()]
elif isinstance(val, list):
FLAT_OBJ[key] = flatten_obj(val, FLAT_OBJ=FLAT_OBJ)
else:
FLAT_OBJ[key] = val
return FLAT_OBJ
Note that the above has one level of recursion, but it's possible the "value" will have a(nother) nested object as well, in which case we want to again extract the _Key,Value. 请注意,以上内容仅具有一个递归级别,但是“值”也可能具有(另一个)嵌套对象,在这种情况下,我们想再次提取_Key,Value。
You can use unpacking with a list comprehension: 您可以将解压缩与列表理解一起使用:
d = {'CollectionTitleIDs': {'852070#TVEpisode': '12', '852063#TVEpisode': '4', '852067#TVEpisode': '9'}, 'ReleaseYear': '2005', 'TVSeriesID': '5638#TVSeries'}
new_d = {**d, 'CollectionTitleIDs':[{'_Key':a, 'Value':b} for a, b in d['CollectionTitleIDs'].items()]}
Output: 输出:
{'CollectionTitleIDs':
[{'_Key': '852070#TVEpisode', 'Value': '12'},
{'_Key': '852063#TVEpisode', 'Value': '4'},
{'_Key': '852067#TVEpisode', 'Value': '9'}],
'ReleaseYear': '2005', 'TVSeriesID': '5638#TVSeries'}
The code should be simpler than that: 该代码应该比这更简单:
in code: 在代码中:
def flatten1(x):
if isinstance(x, list):
return [flatten1(y) for y in x]
elif isinstance(x, dict):
return [{"_Key": key, "Value": flatten1(value)}
for key, value in x.items()]
else:
return x
In your example however for some reason the toplevel is not being flattened and is instead a regular dict, then just do so 但是,在您的示例中,由于某种原因, 顶层没有被扁平化,而是常规的dict,然后只需这样做
def flatten(x):
if isinstance(x, dict):
return {key: flatten1(value) for key, value in x.items()}
else:
return flatten1(x)
flatten1
could even be made an internal function: flatten1
甚至可以做成内部函数:
def flatten(x):
def flatten1(x):
if isinstance(x, list):
return [flatten1(y) for y in x]
elif isinstance(x, dict):
return [{"_Key": key, "Value": flatten1(value)}
for key, value in x.items()]
else:
return x
if isinstance(x, dict):
return {key: flatten1(value) for key, value in x.items()}
else:
return flatten1(x)
My Method: 我的方法:
d={
'CollectionTitleIDs': {
'852070#TVEpisode': '12',
'852063#TVEpisode': '4',
'852067#TVEpisode': '9'
},
'ReleaseYear': '2005',
'TVSeriesID': '5638#TVSeries'
}
d['CollectionTitleIDs'] = list(map(lambda x: {'_Key': x[0], 'Value': x[1]}, d['CollectionTitleIDs'].items()))
#{
# 'CollectionTitleIDs': [
# {'_Key': '852070#TVEpisode', 'Value': '12'},
# {'_Key': '852063#TVEpisode', 'Value': '4'},
# {'_Key': '852067#TVEpisode', 'Value': '9'}
# ],
# 'ReleaseYear': '2005',
# 'TVSeriesID': '5638#TVSeries'
#}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.