收集统计情形下的半手动名单核对

程序目的

在日常的工作中,经常有核对名单的需要,而逐个对照匹配耗时又费力。所以我设想可以通过简单而又快速的方式实现名单核对的功能。

程序简介

  1. 需要准备两个文件:
    1. “问卷预设名单.txt” # 标准名单文件路径
    2. ”待核对名单.txt” # 待核对名单文件路径
  2. 在待核对名单总输入全大写的人名首字母即可,一行一个。
  3. 若有人名首字母相同的情况,会在输出中进行反馈。
  4. 输入仍然以人名全称输出,便于直接阅读。

程序代码

import pandas as pd
from pypinyin import lazy_pinyin, Style
from collections import defaultdict
 
# 读取标准名单和待核对名单 (txt 文件)
def load_names_txt(file_path):
    """
    从txt文件读取名单
    :param file_path: txt文件的路径
    :return: 包含名字的列表
    """
    with open(file_path, 'r', encoding='utf-8') as f:
        # 去掉每行的换行符
        names = [line.strip() for line in f.readlines()]
    return names
 
# 将中文姓名转换为拼音首字母
def name_to_initials(name_list):
    """
    将姓名列表中的名字转换为拼音首字母形式
    :param name_list: 姓名列表
    :return: 拼音首字母列表, 姓名和拼音首字母的对应字典
    """
    initials_list = []
    name_to_initial_dict = defaultdict(list)  # 用于记录每个拼音首字母对应的中文名字
    for name in name_list:
        # 转换为拼音首字母
        initials = ''.join([word[0].upper() for word in lazy_pinyin(name, style=Style.NORMAL)])
        initials_list.append(initials)
        name_to_initial_dict[initials].append(name)  # 记录对应关系
    return initials_list, name_to_initial_dict
 
# 核对名单
def compare_names(standard_names, standard_initials, check_list):
    """
    比较两份名单,找出匹配和未匹配的名字
    :param standard_names: 标准中文名字列表
    :param standard_initials: 标准拼音首字母列表
    :param check_list: 待核对名单
    :return: 匹配的中文名字列表, 未匹配的拼音输入, 标准名单中存在但待核对名单中没有的名字
    """
    matched_names = []
    unmatched_names = []
 
    # 找出待核对名单中存在的
    for check_name in check_list:
        if check_name in standard_initials:
            index = standard_initials.index(check_name)
            matched_names.append(standard_names[index])
        else:
            unmatched_names.append(check_name)
 
    # 找出标准名单中存在但待核对名单中没有的
    missing_names = [name for i, name in enumerate(standard_names) if standard_initials[i] not in check_list]
 
    return matched_names, unmatched_names, missing_names
 
# 检查拼音首字母是否重复
def check_duplicates(name_to_initial_dict, check_list):
    """
    检查待核对名单中拼音首字母是否有重复
    :param name_to_initial_dict: 拼音首字母与名字的对应字典
    :param check_list: 待核对名单
    :return: 返回拼音首字母重复的情况
    """
    duplicates = {}
    for check_name in check_list:
        if check_name in name_to_initial_dict and len(name_to_initial_dict[check_name]) > 1:
            duplicates[check_name] = name_to_initial_dict[check_name]
    return duplicates
 
# 主程序
if __name__ == "__main__":
    # 从txt文件导入名单
    standard_file = r"问卷预设名单.txt"  # 标准名单文件路径
    check_file = r"待核对名单.txt"      # 待核对名单文件路径
 
    standard_names = load_names_txt(standard_file)
    check_names = load_names_txt(check_file)
 
    # 将标准名单中的中文姓名转换为拼音首字母
    standard_initials, name_to_initial_dict = name_to_initials(standard_names)
 
    # 核对名单(使用拼音首字母进行比对,并输出中文名字)
    matched, unmatched, missing = compare_names(standard_names, standard_initials, check_names)
 
    # 检查待核对名单中拼音首字母是否有重复
    duplicates = check_duplicates(name_to_initial_dict, check_names)
 
    # 输出结果
    print(f"匹配的中文名字: {matched}")
    print(f"未匹配的拼音输入: {unmatched}")
    print(f"标准名单中存在但待核对名单中没有的人名: {missing}")
    
    if duplicates:
        print(f"待核对名单中重复的拼音首字母及对应的中文名字: {duplicates}")
    else:
        print("待核对名单中没有拼音首字母重复的情况。")
 

微信接龙格式的直接人名列表核对

特点:需要去掉人名前面的编号或者后面的电话号

 
import re
 
# 读取标准名单和待核对名单 (txt 文件)
def load_names_txt(file_path):
    """
    从txt文件读取名单,并去除人名前后的数字和标点
    :param file_path: txt文件的路径
    :return: 包含名字的列表
    """
    with open(file_path, 'r', encoding='utf-8') as f:
        lines = f.readlines()
    
    # 使用正则表达式去除人名前后的数字和标点
    names = [re.sub(r'^\d+\.?\s*|\d+$', '', line).strip() for line in lines]
    
    return names
 
# 核对名单
def compare_names(standard_names, check_list):
    """
    比较两份名单,找出匹配和未匹配的名字
    :param standard_names: 标准中文名字列表
    :param check_list: 待核对名单
    :return: 匹配的中文名字列表, 未匹配的名字, 标准名单中存在但待核对名单中没有的名字
    """
    matched_names = []
    unmatched_names = []
 
    # 找出待核对名单中存在的
    for check_name in check_list:
        if check_name in standard_names:
            matched_names.append(check_name)
        else:
            unmatched_names.append(check_name)
 
    # 找出标准名单中存在但待核对名单中没有的
    missing_names = [name for name in standard_names if name not in check_list]
 
    return matched_names, unmatched_names, missing_names
 
# 主程序
if __name__ == "__main__":
    # 从txt文件导入名单
    standard_file = r"问卷预设名单.txt"  # 标准名单文件路径
    check_file = r"待核对名单.txt"      # 待核对名单文件路径
 
    standard_names = load_names_txt(standard_file)
    check_names = load_names_txt(check_file)
 
    # 核对名单(直接使用中文名字进行比对)
    matched, unmatched, missing = compare_names(standard_names, check_names)
 
    # 输出结果
    print(f"匹配的中文名字: {matched}")
    print(f"未匹配的名字: {unmatched}")
    print(f"标准名单中存在但待核对名单中没有的人名: {missing}")
 

输入示例

1.刘慈欣
2.莫言

输出示例

匹配的中文名字: [‘刘慈欣’, ‘莫言’]

未匹配的拼音输入: []

标准名单中存在但待核对名单中没有的人名: [‘钱锺书’, ‘余华’, ‘村上春树’]

待核对名单中重复的拼音首字母及对应的中文名字: { }