将树转换为列表列表
我有一个树形结构,大概是这样的:
公司 -> 部门 -> 职位 ->
我有一个三重循环的结构,像这样:
for company in self.Companies():
cName = company.Name()
for dept in company.Departments():
dName = department.Name()
for role in dept.Roles():
rName = role.Name()
roleID = role.ID()
这个 .Name() 函数会返回一个部门名称,比如 Android-Sales。每个公司可以有零个或多个部门。
到目前为止,我只有这些内容。我想进一步开发这个结构,以便得到一个列表的列表:
理想情况下,我希望是这样的。如果有重复的项,列表中的下一个项目应该留空。如果某个字段没有内容,也要留空。
[
['Google', 'Android-Sales', 'Marketer', 'A123'],
['','Google-Play','Developer', 'A435'],
['','','Tester','A125'],
['','','','A126'],
['My Small Company','','Super Role','A123'] ]
或者这样也可以……
[
['Google', 'Android-Sales', 'Marketer', 'A123'],
['Google','Google-Play','Developer', 'A435'],
['Google','Google-Play','Tester','A125'],
['Google','Google-Play','Tester','A126'],
['My Small Company','','Super Role','A123'] (这里“我的小公司”没有部门。
]
每个内部列表的长度应该是4。
3 个回答
除了我之前的回答,你可能还想把一个JSON文件转换成可以放进数据库的元组。在这种情况下,你可以使用下面这个工具包。
不久前,我需要把JSON文件以一种有结构的方式插入到数据库中。根据@Gillespie描述的解决方案,我成功地把文件的层级结构转换成了列表的列表。
下面的脚本会读取一个JSON文件,这个文件里的项目列表最开始是通过父键“value”来识别的。这里有一个简单的data.json
文件的例子。
JSON文件
{
"value":
[
{
"A": 0,
"B": 1,
"C": 2
},
{
"C": {
"E": 3,
"F": 4
},
"D": [
{
"G": 5
},
{
"H": 6
}
]
}
]
}
接下来的脚本会读取这个JSON文件,并把它转换成元组列表,以便插入到数据库中。记得在创建数据库的表和列之前,先去掉特殊字符。
Python脚本
import json
def dict_to_list(sub_tree: dict, current_list: [str], items_list: [[str]]) -> [[str]]:
try: # Tree branches.
for key in sub_tree:
if isinstance(sub_tree[key], list):
for sub_item in sub_tree[key]:
dict_to_list(sub_tree=sub_item, current_list=current_list + [key], items_list=items_list)
elif isinstance(sub_tree[key], dict):
dict_to_list(sub_tree=sub_tree[key], current_list=current_list + [key], items_list=items_list)
else:
items_list.append(current_list + [key] + [sub_tree[key]])
except: # Tree leaf.
items_list.append(current_list + [str(sub_tree)])
return items_list
def json_data_to_samples_list(json_data: dict, data_key: str = 'value', column_sep: str = "_") -> [[(str, str)]]:
samples_list = []
for parent in json_data[data_key]:
column_value_tuples = []
for child in dict_to_list(sub_tree=parent, current_list=[], items_list=[]):
column = column_sep.join(child[:-1])
value = child[-1]
column_value_tuples.append((column, value))
samples_list.append(column_value_tuples)
return samples_list
def main() -> None:
json_file_path = "data.json"
with open(json_file_path, mode="r", encoding="utf-8") as file:
json_data = json.load(file)
samples_list = json_data_to_samples_list(json_data=json_data)
print(f"\nExtracted {len(samples_list)} items from the JSON file:")
for idx, parent in enumerate(samples_list):
print(f"\n>>>>> Child #{idx}:")
for child in parent:
print(f"\t\t{child}")
print()
if __name__ == '__main__':
main()
预期输出
Extracted 2 items from the JSON file:
>>>>> Child #0:
('A', 0)
('B', 1)
('C', 2)
>>>>> Child #1:
('C_E', 3)
('C_F', 4)
('D_G', 5)
('D_H', 6)
试试这样做:
tree = {"Google":{"Android":"yes", "Nexus":"no"}}
list_of_lists = []
def listbuilder(sub_tree, current_list):
for key in sub_tree:
if isinstance(sub_tree[key], dict):
listbuilder(sub_tree[key], current_list + [key])
else:
list_of_lists.append(current_list + [key] + [sub_tree[key]])
listbuilder(tree,[])
print str(list_of_lists)
输出结果:
[['Google', 'Nexus', 'no'], ['Google', 'Android', 'yes']]