210 lines
6.7 KiB
Python
Raw Normal View History

import json
import re
def get_original_order(data, parent_key=''):
"""获取原始字典中所有键的顺序"""
order = []
for key, value in data.items():
current_key = f"{parent_key}.{key}" if parent_key else key
order.append(current_key)
if isinstance(value, dict):
order.extend(get_original_order(value, current_key))
return order
def reorganize_dict(data, original_order):
"""根据原始顺序重新组织字典"""
def get_dict_by_path(d, path):
parts = path.split('.')
current = d
for part in parts[:-1]:
current = current[part]
return current
result = {}
# 按原始顺序重建字典结构
for path in original_order:
parts = path.split('.')
current = result
for i, part in enumerate(parts[:-1]):
if part not in current:
current[part] = {}
current = current[part]
# 获取原始字典中对应路径的值
try:
source_dict = get_dict_by_path(data, path)
current[parts[-1]] = source_dict[parts[-1]]
except KeyError:
# 如果键不存在(可能是被重命名的键),跳过
continue
return result
def generate_key_paths(data, parent_key='', good_list=None, seen=None):
# 保存原始顺序
original_order = get_original_order(data)
if good_list is None:
good_list = []
if seen is None:
seen = set()
key_paths = []
grouped_paths = set()
no_keys_added = True
# Step 1: Collect keys that match the pattern
pattern = re.compile(r'(.+)-\d+$')
prefix_groups = {}
other_keys = []
for key in list(data.keys()):
clean_key = key.replace(" ", "")
match = pattern.match(clean_key)
if match:
prefix = match.group(1)
if prefix not in prefix_groups:
prefix_groups[prefix] = []
prefix_groups[prefix].append(key)
else:
other_keys.append(key)
# Step 2: Handle grouped keys
for prefix, keys in prefix_groups.items():
current_prefix_path = f"{parent_key}.{prefix}" if parent_key else prefix
if len(keys) > 1:
grouped_paths.add(current_prefix_path)
if prefix not in seen:
good_list.append(prefix)
seen.add(prefix)
no_keys_added = False
else:
old_key = keys[0]
new_key = prefix
value = data[old_key]
data[new_key] = value
del data[old_key]
key_path = f"{parent_key}.{new_key}" if parent_key else new_key
key_paths.append(key_path)
if prefix not in seen:
good_list.append(prefix)
seen.add(prefix)
no_keys_added = False
# Step 3: Handle other keys (递归处理其他键)
for key in other_keys:
value = data[key]
current_key = f"{parent_key}.{key}" if parent_key else key
if isinstance(value, dict):
if value:
sub_key_paths, _, sub_grouped_paths, sub_no_keys_added = generate_key_paths(
value, current_key, good_list, seen
)
key_paths.extend(sub_key_paths)
grouped_paths.update(sub_grouped_paths)
no_keys_added = no_keys_added and sub_no_keys_added
else:
clean_key = key.replace(" ", "")
key_paths.append(current_key.replace(" ", ""))
if clean_key not in seen:
good_list.append(clean_key)
seen.add(clean_key)
no_keys_added = False
else:
clean_key = key.replace(" ", "")
key_paths.append(current_key.replace(" ", ""))
if clean_key not in seen:
good_list.append(clean_key)
seen.add(clean_key)
no_keys_added = False
# Step 4: 删除 key_paths 中包含在 grouped_paths 中的元素
key_paths = [path for path in key_paths if path not in grouped_paths]
# 根据原始顺序重新组织字典
reorganized_data = reorganize_dict(data, original_order)
data.clear()
data.update(reorganized_data)
return key_paths, good_list, grouped_paths, no_keys_added
# 示例使用
data1 = {
"采购需求": {
"多媒体会议厅设备": {
"LED屏显示设备": {
"户内全彩LED屏全彩高刷": [],
"发送盒": [],
"LED显示屏控制系统": [],
"视频处理器": [],
"智能配电柜": [],
"台式电脑": [],
"控制桌(定制)": []
},
"LED显示屏施工材料、技术服务费、包装费": {
"结构边框": [],
"线材(按需)": [],
"包装材料": []
},
"扩声系统": {
"主扩全频专业音箱": [],
"专业功放-1": [],
"专业功放-2": [],
"辅助专业音箱": [],
"壁挂支架": [],
"返听专业音箱": [],
"返听专业功放": [],
"超低频专业音箱": [],
"音箱地插": [],
"调音台": [],
"音频处理器": [],
"抑制器": [],
"无线话筒": [],
"话筒呼叫控制嵌入软件": [],
"天线分配器-1": [],
"话筒天线": [],
"有源监听音箱": [],
"电源时序器": []
},
"辅助材料": {
"机柜": [],
"音频连接线-1": [],
"音频连接线-2": [],
"音频连接线-3": [],
"其它辅材(音箱线、电源线、网线、视频线等)": []
},
"会议座椅": {
"会议座椅": []
},
"电动窗帘": {
"电动窗帘系统": []
}
},
"云平台及备课电脑": {
"备课一体机电脑": [],
"云平台管理软件": [],
"教学互动应用软件": []
},
"办公桌椅": {
"办公桌椅": []
},
"文件柜": {
"文件柜": []
},
"体育运动器材": {
"移动式标准篮球架12座": []
}
}
}
key_paths, good_list, grouped_paths, no_keys_added = generate_key_paths(data1)
print(json.dumps(data1,ensure_ascii=False,indent=4))
print(key_paths)
print(grouped_paths)