同学有两张工人名单(排序无规律,名单不完全重合,但人名有重复),要按其中一张表的顺序,填入另一张表的工资卡信息。由于数据量巨大,靠人工一行行查找,复制粘贴非常费时,求助于我。故写如下代码以解决此类问题:
因是初学者,故添加了大量注释以学习,还望海涵。非常讨厌英文,凡是能用中文的都用。
'''
有A表格导出数据“原名单.txt”与B表格导出数据“数据名单”
其中,A表格与B表格各自排序不同
但两表格有部分人员重叠,B表格有账号及银行数据
现在要将B表格里的相关数据按A表格的排序填充到A表格中,无数据放空
'''
'''
思路:
关键词:扁平化
1,按行分别导入两表格
2,分别规范化两表格
2,提取A表格的身份证号,遍历B表格,如果重合,则将对应的账号及
银行填入A表格中
3,输出结果到C表格
'''
原名单路径=r'H:\python\不同顺序的表格填充数据\原名单.txt'
数据名单路径=r'H:\python\不同顺序的表格填充数据\数据名单.txt'
预输出名单路径=r'H:\python\不同顺序的表格填充数据\预输出名单.txt'
输出名单路径=r'H:\python\不同顺序的表格填充数据\输出名单.txt'
#1-1 打开原名单
with open(原名单路径, 'r', encoding='utf-8-sig') as 文件:
原名单 = []
行列表 = 文件.readlines()
#print (f'"行列表"是列表:\n{行列表}')
#规范化原名单数据
for 变量 in 行列表:
变量=变量.replace('\t',' ').replace('\n','')
#print(f'"变量"是字符串:\n{变量}')
# 按空格创建子列表
子列表=变量.split()
#print (f'"子列表"是列表:\n{子列表}')
原名单.append(子列表)
#print (f'"原名单"是母列表:\n{原名单}')
#print (f'"原名单"是母列表,退出with后仍然可调用:\n{原名单}')
#1-2 打开数据名单
with open(数据名单路径, 'r', encoding='utf-8-sig') as 文件:
数据名单 = []
行列表 = 文件.readlines()
#print (f'"行列表"是列表:\n{行列表}')
#规范化数据名单数据
for 变量 in 行列表:
变量=变量.replace('\t',' ').replace('\n','')
#print(f'"变量"是字符串:\n{变量}')
# 按空格创建子列表
子列表=变量.split()
#print (f'"子列表"是列表:\n{子列表}')
数据名单.append(子列表)
#print (f'"数据名单"是母列表:\n{数据名单}')
#print (f'"数据名单"是母列表,退出with后仍然可调用:\n{数据名单}')
#对比两张表格
#复制一份原名单列表和数据名单列表,不能用原始数据进行处理
备份原名单=原名单[:]
备份数据名单=数据名单[:]
计数=0
print ('数据处理中,请稍候……')
for 原名单身份信息 in 备份原名单:
#“原名单身份信息”是子列表;“备份原名单”是母列表
样品变量=原名单身份信息[0]
#print (样品变量)
#获取“原名单”列表的第0个元素
for 数据名单身份信息 in 备份数据名单:
#“数据名单身份信息”是子列表;“备份数据名单”是母列表
受检变量=数据名单身份信息[0]
#print (受检变量)
#break
#设置断点,以检查此处的变量值是否正确
# 遍历查找身份证号相同的子列表
#由于原名单与数据名单里都存在着重名,故当第一次检测出“样品变量==受检变量”时,
# 程序将数据名单第一个重名组的账号与银行信息追加到原名单的末尾;
#但当第二个重名组也满足“样品变量==受检变量”时,程序又将第二个重名组的账号与
# 银行信息追加到原名单的末尾。
# 这导致了原名单的最终结果末尾有两组相同的账号与银行信息。
# 若针对“受检变量”设置重名检查,或针对追加的银行信息设置重复检查,则会导致原名单的第二个重复人员
# 无法追加任何银行信息。反复调试未能解决。
#故,决定:不设置重名检查,在生成新列表后对新列表进行倒序间隔式重复检查,重复项pop掉
if 样品变量==受检变量:
#预加载要追加的银行信息
银行信息列表=数据名单身份信息[2:]
#print (银行信息列表)
#break
# 设置断点,以检查此处的变量值是否正确
for 变量 in 银行信息列表:
原名单身份信息.append(变量)
#print (原名单身份信息)
#break
# 设置断点,以检查此处的变量值是否正确
#对新生成的列表“原名单身份信息”进行倒序重复项检查,间隔一个索引号检重复项
for 重复数 in range(len(原名单身份信息)-2):
if 原名单身份信息[-1]==原名单身份信息[len(原名单身份信息)-3]:
#pop()方法删除列表最后一个元素
原名单身份信息.pop()
计数 += 1
#计数 += 1等价于:计数=计数+1
print (f'完成{计数}条数据')
#print (原名单身份信息)
print ('开始打印处理结果:')
for 变量 in 备份原名单:
print (变量)
#输出到文本文件
import sys
with open(预输出名单路径,'w', encoding='utf-8-sig') as 文件:
sys.stdout=文件
# .stdout:标准输出,将下面的打印内容输出到文本文件中
for 变量 in 备份原名单:
print(变量)
#打开文件,清除标点
import string
import os
要删除的标点=['[',']',"'",]
with open(预输出名单路径,'a+', encoding='utf-8-sig') as 文件:
sys.stdout = 文件
#执行sys.stdout=文件之后,对“文件”的任何操作也将对sys.stdout执行。
#离开with块会关闭“文件”,因此它也会关闭sys.stdout。然后,当您稍后
#执行print时,它尝试将此写入sys.stdout,但它已关闭,因此会得到一
#个错误:ValueError: I/O operation on closed file。
#所以打开第二个文件后,需要再次使用sys.stdout=文件
文件.seek(0)
#因为上面的“with open(写入文件路径,'a+',encoding='utf-8-sig')as 文件:”
#中使用的是“a+”,以读写模式打开文件,指针在文件尾。故要将其
#复位到文件头,否则下面的read()方法读不到内容
with open(输出名单路径, 'w', encoding='utf-8-sig') as 结果:
sys.stdout = 结果
#因为要写入一个新的文件,而不对原文件操作,所以这里用sys.stdout = 结果
内容=文件.read()
#读取“预输出名单”的内容
for 标点 in 要删除的标点:
内容=内容.replace(标点,'').replace(',',' ')
#多个replace()方法连用,把要删除的标点替换为空,把逗号替换为空格
print (内容)
#把处理完的内容写到文本文件中
# 删除临时文件
os.remove(预输出名单路径)
#用操作系统默认程序打开上述文件
os.startfile(输出名单路径)
将出东方
2023-03-05