Skip to content

Instantly share code, notes, and snippets.

@iqiancheng
Last active September 5, 2023 03:03
Show Gist options
  • Save iqiancheng/22ea43e7c349f2ad9df6063aa1bd32a3 to your computer and use it in GitHub Desktop.
Save iqiancheng/22ea43e7c349f2ad9df6063aa1bd32a3 to your computer and use it in GitHub Desktop.
既可以加载严格json格式的json,又可以加载Python 代码中的单引号格式的json,且最后一行k-v之后有"," 也不会报错的Python工具类
import json
class FlexibleJSONLoader:
@staticmethod
def load(file_path):
with open(file_path, 'r') as file:
content = file.read()
content = FlexibleJSONLoader._fix_commas(content)
try:
data = json.loads(content)
return data
except json.JSONDecodeError as e:
print(f"Error decoding JSON: {e}")
return None
@staticmethod
def flexible_load(file_path):
data = None
try:
with open(file_path, 'r') as file:
content = file.read()
if "': '" in content or "':'" in content:
logger.warning(f"WARN: load flexible JSON.")
data = eval(content.strip())
else:
data = json.loads(content)
except json.JSONDecodeError as e:
logger.error(f"Error decoding JSON: {e}")
return data
@staticmethod
def _fix_commas(content):
lines = content.split('\n')
fixed_lines = []
for line in lines:
line = line.strip()
line = line.replace('"', '').replace("'", '"')
if line.startswith("# "): # fix comment like # "Cookie": "uuc-vlang=zh-CN; ...
line = line[2:]
if line and line[-1] == ',':
line = line[:-1]
if line != '' and line is not None:
fixed_lines.append(line)
k_v = ',\n'.join(fixed_lines[1:-1])
fixed_json = f'{{\n{k_v}\n}}'
return fixed_json
@staticmethod
def _fix_lines(line):
line = line.strip()
fixed_line = line.replace('"', '').replace("'", '"')
return fixed_line
@staticmethod
def read_lines(file_path):
lines = []
with open(file_path, 'r', encoding='utf-8') as file:
for line in file:
if line and "'" in line:
line = FlexibleJSONLoader._fix_lines(line)
lines.append(json.loads(line))
return lines
@staticmethod
def write_lines(data_list, output_filepath):
with open(output_filepath, 'w', encoding='utf-8-sig') as file:
for data in data_list:
json.dump(data, file, ensure_ascii=False)
file.write('\n')
@staticmethod
def multi_lines_convert_to_jsonl(input_filepath, output_filepath):
FlexibleJSONLoader.write_lines(FlexibleJSONLoader.read_lines(input_filepath), output_filepath)
# 使用示例
if __name__ == "__main__":
# json_path = 'config/header.json' # 替换为你的JSON文件路径
# loaded_data = FlexibleJSONLoader.load(json_path)
# if loaded_data:
# print(loaded_data)
# multi_json_lines read and write
jsonl_path = 'jsonl.txt'
data_list = FlexibleJSONLoader.read_lines(jsonl_path)
if data_list:
print(data_list)
FlexibleJSONLoader.write_lines(data_list, 'test.jsonl')
# 写入数据
data_to_write = [
{"name": "Alice", "age": 30},
{"name": "Bob", "age": 25},
{"name": "Charlie", "age": 40}
]
FlexibleJSONLoader.write_lines(data_to_write, 'students.jsonl')
pass

下面是一个可以满足你需求的Python工具类代码示例。该工具类使用了json库来处理JSON格式,可以加载严格的JSON和Python代码中的单引号格式的JSON。在处理最后一行的逗号问题上,它会自动处理,不会引发错误。

import json

class FlexibleJSONLoader:
    @staticmethod
    def load(file_path):
        with open(file_path, 'r') as file:
            content = file.read()
            content = FlexibleJSONLoader._fix_commas(content)
            try:
                data = json.loads(content)
                return data
            except json.JSONDecodeError as e:
                print(f"Error decoding JSON: {e}")
                return None

    @staticmethod
    def _fix_commas(content):
        lines = content.split('\n')
        fixed_lines = []

        for line in lines:
            line = line.strip()
            line = line.replace('"', '').replace("'", '"')
            if line.startswith("# "): # fix comment like # "Cookie": "uuc-vlang=zh-CN; ...
                line = line[2:]
            if line and line[-1] == ',':
                line = line[:-1]
            if line != '' and line is not None:
                fixed_lines.append(line)

        k_v = ',\n'.join(fixed_lines[1:-1])
        fixed_json = f'{{\n{k_v}\n}}'
        return fixed_json

    @staticmethod
    def _fix_lines(line):
        line = line.strip()
        fixed_line = line.replace('"', '').replace("'", '"')
        return fixed_line

    @staticmethod
    def read_lines(file_path):
        lines = []
        with open(file_path, 'r', encoding='utf-8') as file:
            for line in file:
                if line and  "'" in line:
                    line = FlexibleJSONLoader._fix_lines(line)
                lines.append(json.loads(line))
        return lines

    @staticmethod
    def write_lines(data_list, output_filepath):
        with open(output_filepath, 'w', encoding='utf-8-sig') as file:
            for data in data_list:
                json.dump(data, file, ensure_ascii=False)
                file.write('\n')

    @staticmethod
    def multi_lines_convert_to_jsonl(input_filepath, output_filepath):
        FlexibleJSONLoader.write_lines(FlexibleJSONLoader.read_lines(input_filepath), output_filepath)

# 使用示例
if __name__ == "__main__":
    # json_path = 'config/header.json'  # 替换为你的JSON文件路径
    # loaded_data = FlexibleJSONLoader.load(json_path)
    # if loaded_data:
    #     print(loaded_data)

    # multi_json_lines read and write
    jsonl_path = 'jsonl.txt'
    data_list = FlexibleJSONLoader.read_lines(jsonl_path)
    if data_list:
        print(data_list)
        FlexibleJSONLoader.write_lines(data_list, 'test.jsonl')

    # 写入数据
    data_to_write = [
        {"name": "Alice", "age": 30},
        {"name": "Bob", "age": 25},
        {"name": "Charlie", "age": 40}
    ]
    FlexibleJSONLoader.write_lines(data_to_write, 'students.jsonl')
    pass

请将上述代码保存到一个Python文件中(例如json_loader.py),并将你的JSON文件放在同一目录下,然后运行这个Python文件。这个工具类会尝试加载JSON文件并自动处理最后一行的逗号问题。

记得在使用前安装json库,你可以使用以下命令安装:

pip install json5

这个示例使用了json5库来处理Python代码中的单引号格式的JSON,以及自动修复最后一行的逗号。如果你还没有安装json5库,可以通过上述命令进行安装。

注意:虽然这个工具类可以满足你的需求,但是在处理复杂的情况下可能会有限制。如果你需要处理更复杂的JSON格式,可能需要更加详细的处理逻辑。

{'classOne': '逻辑与数学', 'classTwo': '上下文学习', 'classThree': '情感分析', 'query': '【指令】\n你是外卖评论分析员,你正在标注用户评论:\n评论:没吃过这么难吃的外卖\n标注:负向\n评论:量很足!地三鲜好吃!\n标注:正向\n评论:这个肠粉不正宗,但在重庆也算不错\n标注:中性\n评论:这点量还不够我塞牙缝的!\n标注:', 'prompt': '【指令】\n你是外卖评论分析员,你正在标注用户评论:\n评论:没吃过这么难吃的外卖\n标注:负向\n评论:量很足!地三鲜好吃!\n标注:正向\n评论:这个肠粉不正宗,但在重庆也算不错\n标注:中性\n评论:这点量还不够我塞牙缝的!\n标注:', 'label': '逻辑与数学-上下文学习-情感判断_330.xlsx\tSheet1', 'extract_key': 'classOne\tclassTwo\tclassThree\t', 'sheetname': 'Sheet1'}
{'classOne': '逻辑与数学', 'classTwo': '上下文学习', 'classThree': '情感分析', 'query': '【指令】\n你是影评分析员,你正在标注用户评论:\n评论:现在国产科幻片就这?\n标注:负向\n评论:真正的神作\n标注:正向\n评论:符合预期,还有一定的进步空间\n标注:中性\n评论:从定档就在期待了!符合预期!\n标注:', 'prompt': '【指令】\n你是影评分析员,你正在标注用户评论:\n评论:现在国产科幻片就这?\n标注:负向\n评论:真正的神作\n标注:正向\n评论:符合预期,还有一定的进步空间\n标注:中性\n评论:从定档就在期待了!符合预期!\n标注:', 'label': '逻辑与数学-上下文学习-情感判断_330.xlsx\tSheet1', 'extract_key': 'classOne\tclassTwo\tclassThree\t', 'sheetname': 'Sheet1'}
{'classOne': '逻辑与数学', 'classTwo': '上下文学习', 'classThree': '情感分析', 'query': '【指令】\n你是游戏论坛管理员,你正在判断帖子的内容\n内容:我觉得这个游戏迟早要完\n判断:负面\n内容:现在给大家分享一个新的配队思路\n判断:正面\n内容:就事论事,这次活动在剧情方面做得一般\n判断:中性\n内容:什么垃圾游戏退游了\n判断:', 'prompt': '【指令】\n你是游戏论坛管理员,你正在判断帖子的内容\n内容:我觉得这个游戏迟早要完\n判断:负面\n内容:现在给大家分享一个新的配队思路\n判断:正面\n内容:就事论事,这次活动在剧情方面做得一般\n判断:中性\n内容:什么垃圾游戏退游了\n判断:', 'label': '逻辑与数学-上下文学习-情感判断_330.xlsx\tSheet1', 'extract_key': 'classOne\tclassTwo\tclassThree\t', 'sheetname': 'Sheet1'}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment