144 lines
6.3 KiB
Python
144 lines
6.3 KiB
Python
# -*- encoding:utf-8 -*-
|
||
import json
|
||
import re
|
||
|
||
|
||
def is_numeric_key(key):
|
||
# 这个正则表达式匹配由数字、点、括号中的数字或单个字母(小写或大写)组成的字符串,
|
||
# 字母后跟数字,或数字后跟字母,单个字母后跟点,但不能是字母-数字-字母的组合
|
||
pattern = r'^[\d.]+$|^\(\d+\)$|^(\d+)$|^[a-zA-Z]$|^[a-zA-Z]\d+$|^\d+[a-zA-Z]$|^[a-zA-Z]\.$'
|
||
return re.match(pattern, key) is not None
|
||
|
||
|
||
def contains_number_or_index(key, value):
|
||
# 判断值是否是数字或数字字符串
|
||
is_number = isinstance(value, (int, float)) or (isinstance(value, str) and value.isdigit())
|
||
# 判断键是否包含 "序号"
|
||
contains_index = '序号' in key
|
||
# 判断值中是否包含数字
|
||
contains_digit = isinstance(value, str) and re.search(r'\d+', value)
|
||
# 判断值中是否包含中文字符
|
||
contains_chinese = isinstance(value, str) and re.search(r'[\u4e00-\u9fff]', value)
|
||
# 如果值中包含数字但也有中文字符,则保留(返回 False)
|
||
if contains_digit and contains_chinese:
|
||
return False
|
||
# 如果值是数字或包含数字,且不包含中文字符,或者键包含 "序号",返回 True
|
||
return is_number or contains_index or contains_digit
|
||
def preprocess_dict(data):
|
||
if isinstance(data, dict):
|
||
if len(data) > 1:
|
||
# 检查是否所有值都是 "" 或 "/"
|
||
if all(v == "" or v == "/" or (isinstance(v, list) and not v) for v in data.values()):
|
||
return list(data.keys())
|
||
else:
|
||
processed = {}
|
||
for k, v in data.items():
|
||
if not contains_number_or_index(k, v):
|
||
processed_v = preprocess_dict(v)
|
||
if processed_v != "": # 只添加非空值
|
||
processed[k] = processed_v
|
||
return processed
|
||
else:
|
||
return {k: preprocess_dict(v) for k, v in data.items()}
|
||
elif isinstance(data, list):
|
||
return [preprocess_dict(item) for item in data]
|
||
else:
|
||
return data
|
||
|
||
def process_dict(data):
|
||
"""
|
||
递归处理字典,将符合条件的键值对进行转换。
|
||
|
||
如果键是数字或特定格式的字符串,则将其值放入 'items' 列表中并排序。
|
||
对于非数字键,如果对应的值是列表且列表中只有一个元素,则将其展平为单个元素。
|
||
|
||
Args:
|
||
data (dict): 输入的字典数据。
|
||
|
||
Returns:
|
||
dict 或 list 或 原始数据类型: 处理后的数据结构。
|
||
"""
|
||
if not isinstance(data, dict):
|
||
return data
|
||
|
||
result = {}
|
||
numeric_keys = []
|
||
non_numeric_keys = {}
|
||
|
||
# 分类键为数字键和非数字键
|
||
for key, value in data.items():
|
||
if is_numeric_key(key):
|
||
numeric_keys.append((key, value))
|
||
else:
|
||
non_numeric_keys[key] = value
|
||
|
||
# 处理数字键,将其值递归处理后放入 'items' 列表中
|
||
if numeric_keys:
|
||
def sort_key(item):
|
||
key = item[0]
|
||
if re.match(r'^\d+$', key): # 纯整数
|
||
return (int(key),)
|
||
elif re.match(r'^\d+\.\d+$', key): # 单层小数点
|
||
return (float(key),)
|
||
else: # 多层序号,按字符串处理
|
||
return tuple(map(int, key.split('.')))
|
||
# 按键排序,确保顺序一致
|
||
numeric_keys_sorted = sorted(numeric_keys, key=sort_key)
|
||
result['items'] = [process_dict(item[1]) for item in numeric_keys_sorted]
|
||
|
||
# 处理非数字键
|
||
for key, value in non_numeric_keys.items():
|
||
if isinstance(value, list):
|
||
processed_list = []
|
||
for item in value:
|
||
if isinstance(item, dict):
|
||
# 处理字典中只有一个键值对的情况
|
||
if len(item) == 1:
|
||
processed_item = process_dict(list(item.values())[0])
|
||
else:
|
||
processed_item = process_dict(item)
|
||
else:
|
||
processed_item = process_dict(item)
|
||
|
||
# 如果处理后的项是只包含一个元素的列表,则展平它
|
||
if isinstance(processed_item, list) and len(processed_item) == 1:
|
||
processed_item = processed_item[0]
|
||
|
||
processed_list.append(processed_item)
|
||
|
||
# 新增逻辑:如果 processed_list 只有一个元素,则将其展平为单个元素
|
||
if len(processed_list) == 1:
|
||
result[key] = processed_list[0]
|
||
else:
|
||
result[key] = processed_list
|
||
else:
|
||
# 如果值不是列表,直接递归处理
|
||
result[key] = process_dict(value)
|
||
|
||
# 如果结果只有一个键 'items',则直接返回 'items' 列表
|
||
if len(result) == 1 and 'items' in result:
|
||
return result['items']
|
||
|
||
# 检查如果所有键对应的值都是空列表,则将键名转换成列表项
|
||
if all(isinstance(v, list) and not v for v in result.values()):
|
||
return list(result.keys())
|
||
|
||
return result
|
||
data={
|
||
"资格性审查": {
|
||
"1": "供应商应具备《政府采购法》第二十二条规定的条件,提供相关材料。",
|
||
"2": "法人或者其他组织的营业执照等证明文件,自然人的身份证明;",
|
||
"3": "财务状况报告,依法缴纳税收和社会保障资金的声明函;",
|
||
"4": "具备履行合同所必需的设备和专业技术能力的证明材料;",
|
||
"5": "未被列入信用记录名单声明函;",
|
||
"6": "参加政府采购活动前 3年内在经营活动中没有重大违法记录的书面声明;",
|
||
"7": "具备法律、行政法规规定的其他条件的证明材料;",
|
||
"8": "招标文件第一章“投标人资格要求”中有特殊要求的,投标人应提供其符合特殊要求的证明材料或者情况说明;",
|
||
"9.1.1": "未被列入信用记录名单声明函;",
|
||
"10.1.1": "参加政府采购活动前 3年内在经营活动中没有重大违法记录的书面声明;",
|
||
"11": "具备法律、行政法规规定的其他条件的证明材料;",
|
||
"12": "招标文件第一章“投标人资格要求”中有特殊要求的,投标人应提供其符合特殊要求的证明材料或者情况说明;"
|
||
}
|
||
}
|
||
res1=process_dict(preprocess_dict(data))
|
||
print(json.dumps(res1,ensure_ascii=False,indent=4)) |