Loading... ## Python基础语法项目实践-自动化录入数据 ### 项目背景 某同学需要调研市区里的住宅小区,记录下不同小区的地址、建筑年份和每栋楼里每个单元里每一户的朝向和面积。比如其中一户的资料是:富安花园(小区)3栋 2单元 401户;朝向:南北朝向;面积:90平方。他需要把每一户的信息都记录下来。一般会将一栋楼的数据画在一张平面图,之后再慢慢录入到excel里面,但面对这样的情况,一旦遇到不同单元的户数、朝向和面积,就无法进行复制,而一遍遍的输入数据将会十分心累且耗费时间!一旦出错,难以发现以及改变很费劲,牵连甚广。  于是需求应运而生,如何用python输入模板数据,程序自动录入剩下的数据,甚至不用打开excel   ### 拆解项目 目标是将一个小区某一栋内所有户室的资料录入到excel表里  简易的流程图可以看一下:  可以分三个版本逐渐迭代 ### 1.0版本:输入固定表头,确定模板数据 用Python读写excel的时候,可以调用csv模块,下面将向csv里写入表头 ``` python import csv #调用csv模块 with open('data.csv', 'a', newline='') as csvfile: #调用open()函数打开csv文件,传入参数:文件名“data.csv”、追加模式“a”、newline=''。 writer = csv.writer(csvfile, dialect='excel') # 用csv.writer()函数创建一个writer对象。 header=['小区名称', '地址', '建筑年份', '楼栋', '单元', '户室', '朝向', '面积'] writer.writerow(header) #用writerow()函数将表头写进csv文件里 ``` 将以上的复制到本地编辑器,可以看到新建了一个名为data.csv文件,打开如下:  如果是mac os,遇到了乱码,则需要在`open()`函数里加上参数`endoding='GBK'` ``` python with open('data.csv', 'a', newline='',encoding='GBK') as csvfile: #确定编码 ``` 下面就是确定哪些数据是可以一次输入重复利用,小区的名称、建筑年代、地址、楼号是可以重复使用的,但同一栋的单元内分布是各有不同的,楼型不同户型也不一样。放大到同一单元下,每一层的户型和朝向一般是一样的,所以只需要某一层的数据,就可以知道其他楼层的,区别只是户室号。确定了以此为模板数据,下一步就是转化成代码。 ``` python title = input('请输入小区名称') address = input('请输入小区地址:') year = input('请输入小区建造年份:') block = input('请输入楼栋号:') #输入可重复利用利用的数据 ``` ### 2.0版本:获取模板数据,重复使用模板数据 户室号一般有楼层+两位序号组成,比如101,102,201,202等,尾号是统一的,变化则根据楼层数而变化。根据图片可以看出每个户室的朝向和面积是并列关系,从属于户室的。  通过使用字典嵌套列表的形式,来实现数据的组合,字典的键是户室号,面积和朝向组成的列表为字典的值。类似如下形式 ``` python start_floor_rooms = {301:['南北',70],302:['南北',70],303:['东西',80],304:['东西',80]} #初始楼层的数据 ``` 那么具体输入的代码如下所示: ``` python start_floor = input('请输入起始楼层') end_floor = input('请输入终止楼层') #获取每一单元楼层数 start_floor_room = {} floor_last_number = [] #创建字典,存放户室信息;创建列表,存放户室尾号如['01','02'],后续楼层即可重复使用 last_number = input('请输入起始楼层户室的尾号:(如01,02)') floor_last_number.append(last_number) #将输入的元素添加到户室尾号的列表里 room_number = int(start_floor + last_number) #户室号由起始楼层和户室尾号组成,如301 direction = int(input('请输入 %d朝向(南北朝向输入1,东西朝向输入2):' % room_number)) #收集该户室的朝向信息 area = int(input('请输入 %d 的面积,单位为㎡:' % room_number)) #收集该户室的面积信息 start_floor_room[room_number] = [direction,area] #户室号为键,朝向和面积均为值,添加到字典里 print(start_floor_room) #打印起始楼层数据 ``` 运行结果如下:  这样我们就获取了一个户室的信息,但如果要获取起始楼层其他户室的信息,则需要加入循环。 ``` python start_floor = input('请输入起始楼层') end_floor = input('请输入终止楼层') #获取每一单元楼层数 input('接下来请依次输入起始层每个房间的户室尾号、南北朝向及面积,按任意键继续') start_floor_room = {} floor_last_number = [] #创建字典,存放户室信息;创建列表,存放户室尾号如['01','02'],后续楼层即可重复使用 #定义循环控制量 room_loop = True while room_loop: last_number = input('请输入起始楼层户室的尾号:(如01,02)') floor_last_number.append(last_number) #将输入的元素添加到户室尾号的列表里 room_number = int(start_floor + last_number) #户室号由起始楼层和户室尾号组成,如301 direction = int(input('请输入 %d朝向(南北朝向输入1,东西朝向输入2):' % room_number)) #收集该户室的朝向信息 area = int(input('请输入 %d 的面积,单位为㎡:' % room_number)) #收集该户室的面积信息 start_floor_room[room_number] = [direction,area] #户室号为键,朝向和面积均为值,添加到字典里 continued = input('是否需要输入下一个尾号?按 n 停止输入,按其他任意键继续录入') if continued == 'n': room_loop = False else: room_loop = True print(start_floor_room) #打印起始楼层数据 ``` 运行结果如下:  到这一步,已经将起始楼层的所有户室数据收集到了,下一步则只要将这层的数据迁移到其他楼层中即可。  为了更好的管理数据,将所有楼层的数据放在一起会更好管理,也就是字典嵌套字典的方式。  那么根据此方法,对刚才的代码再次进行添加,如下: ``` python start_floor = '3' end_floor = '4' floor_last_number = ['01','02','03'] # 之前input()输入的数据为str类型 start_floor_rooms = {301:[1,80], 302:[1,80], 303:[2,90]} #初始楼层的模版数据 unit_rooms = {} #创建一个字典,存储所有楼层的数据 unit_rooms[int(start_floor)] = start_floor_rooms #unit_rooms = {3: {301: [1, 80], 302: [1, 80], 303: [2, 90]}} floor_rooms = {} #给4楼创建一个字典 for i in range(len(start_floor_rooms)): #遍历每层有多少个房间,这里是3,即执行for i in range 3 的循环 number = '4' + floor_last_number[i] #字符串拼接, number = ['401','402','403'] info = start_floor_rooms[int(start_floor + floor_last_number[i])] # 依次取出字典start_floor_rooms键对应的值,即面积和朝向组成的列表 # int(start_floor + floor_last_number[0])= 301 # info = [1,80] floor_rooms[int(number)] = info #给字典floor_rooms添加键值对,floor_rooms = {401:[1,80]} #循环三次,所以floor_rooms = {401:[1,80], 402:[1,80], 403:[2,90]} unit_rooms[4] = floor_rooms #以4为键,floor_rooms为值,给字典unit_rooms添加键值对 print(unit_rooms) #unit_rooms = {3: {301: [1, 80], 302: [1, 80], 303: [2, 90]}, 4: {401: [1, 80], 402: [1, 80], 403: [2, 90]}} ``` 运行结果如下: ``` python {3: {301: [1, 80], 302: [1, 80], 303: [2, 90]}, 4: {401: [1, 80], 402: [1, 80], 403: [2, 90]}} ``` 接下来继续假如循环,将所有楼层数据一次性放进字典`unit_rooms`里。如果是3-7楼,我们的循环执行4,5,6,7四次,循环条件可以写成: ``` python for floor in range(start_floor + 1, end_floor + 1): # 在此例中,为 for floor in range (4,8) ``` 那么将循环写入上一步,结果就是: ``` python start_floor = '3' end_floor = '7' floor_last_number = ['01','02','03'] start_floor_rooms = {301:[1,80],302:[1,80],303:[2,90]} #初始楼层的模版数据 unit_rooms = {} #新建一个存放所有楼层的字典 unit_rooms[int(start_floor)] = start_floor_rooms for floor in range(int(start_floor) + 1, int(end_floor) + 1): #遍历除初始楼层外的其他楼层 floor_rooms = {} #每个楼层都建立一个字典 for i in range(len(start_floor_rooms)): #遍历每层有多少个房间,这里是3,即执行for i in range 3 的循环 number = str(floor) + floor_last_number[i] info = start_floor_rooms[int(start_floor + floor_last_number[i])] # 依次取出字典start_floor_rooms键对应的值,即面积和朝向组成的列表 floor_rooms[int(number)] = info #给字典floor_rooms添加键值对,floor_rooms = {401:[1,80]} unit_rooms[floor] = floor_rooms print(unit_rooms) ``` 运行结果如下: ``` python {3: {301: [1, 80], 302: [1, 80], 303: [2, 90]}, 4: {401: [1, 80], 402: [1, 80], 403: [2, 90]}, 5: {501: [1, 80], 502: [1, 80], 503: [2, 90]}, 6: {601: [1, 80], 602: [1, 80], 603: [2, 90]}, 7: {701: [1, 80], 702: [1, 80], 703: [2, 90]}} ``` ### 3.0版本:写入CSV文件 再看一遍开头输入的表头  名称、地址、建筑年份、楼栋、单元都需要手动输入,输入一遍即可复用到其他所有单元格里。 ``` python title = input('请输入小区名称') address = input('请输入小区地址:') year = input('请输入小区建造年份:') block = input('请输入楼栋号:') unit = input('请输入单元号:') ``` 剩下户室信息,“朝向”、“面积”都储存在字典`unit_rooms`里,接着需要对字典内信息进行提取。首先就要提取字典里的值,也就是大字典中的小字典 ``` python # for value in DictName.values(): # value的名字可以自行另取 # DictName是要遍历的字典的名称 # .values():是固定的用法 unit_rooms = {3:{301:[1,80],302:[1,80],303:[2,90],304:[2,90]}, 4:{401:[1,80],402:[1,80],403:[2,90],404:[2,90]}, 5:{501:[1,80],502:[1,80],503:[2,90],504:[2,90]} } for sub_dict in unit_rooms.values(): print(sub_dict) ``` 提取出小字典后,接着需要遍历小字典的键和值,可以用`for k,v in DictName.items():`,k对应键,v对应值,通过小例子可以直观的感受一下: ``` python tv_dict = {'芒果台':'湖南卫视', '荔枝台':'江苏卫视', '番茄台':'东方卫视'} for logo,name in tv_dict.items(): print(logo + '是' + name) ``` 运行结果如下: ``` python 芒果台是湖南卫视 荔枝台是江苏卫视 番茄台是东方卫视 ``` 那么运用该方法打印每一户室的门牌号、朝向和面积,如下: ``` python unit_rooms = {3:{301:[1,80],302:[1,80],303:[2,90],304:[2,90]}, 4:{401:[1,80],402:[1,80],403:[2,90],404:[2,90]}, 5:{501:[1,80],502:[1,80],503:[2,90],504:[2,90]} } for sub_dict in unit_rooms.values(): for room,info in sub_dict.items(): print('户室号:%d 朝向 %d 面积:%d'% (room,info[0],info[1])) ``` 运行结果如下: ``` python 户室号:301 朝向 1 面积:80 户室号:302 朝向 1 面积:80 户室号:303 朝向 2 面积:90 户室号:304 朝向 2 面积:90 户室号:401 朝向 1 面积:80 户室号:402 朝向 1 面积:80 户室号:403 朝向 2 面积:90 户室号:404 朝向 2 面积:90 户室号:501 朝向 1 面积:80 户室号:502 朝向 1 面积:80 户室号:503 朝向 2 面积:90 户室号:504 朝向 2 面积:90 ``` 朝向显示数字总觉得会怪怪的,可以运用条件判断和赋值语句,也可以通过列表索引的方式进行更改。 ``` python unit_rooms = {3:{301:[1,80],302:[1,80],303:[2,90],304:[2,90]}, 4:{401:[1,80],402:[1,80],403:[2,90],404:[2,90]}, 5:{501:[1,80],502:[1,80],503:[2,90],504:[2,90]} } for sub_dict in unit_rooms.values(): for room,info in sub_dict.items(): dire = ['', '南北', '东西'] print('户室号:%d 朝向:%s 面积:%d' % (room,dire[info[0]],info[1])) ``` 输出结果为: ``` python 户室号:301 朝向: 南北 面积:80 户室号:302 朝向: 南北 面积:80 户室号:303 朝向: 东西 面积:90 户室号:304 朝向: 东西 面积:90 户室号:401 朝向: 南北 面积:80 户室号:402 朝向: 南北 面积:80 户室号:403 朝向: 东西 面积:90 户室号:404 朝向: 东西 面积:90 户室号:501 朝向: 南北 面积:80 户室号:502 朝向: 南北 面积:80 户室号:503 朝向: 东西 面积:90 户室号:504 朝向: 东西 面积:90 ``` 到这为止,需求差不多基本满足了,再加入一层单元间的循环即可完成最后的代码,最终代码如下: ``` python import csv #调用csv模块 with open('data.csv', 'a', newline='') as csvfile: #调用open()函数打开csv文件,传入参数:文件名“data.csv”、追加模式“a”、newline=''。 writer = csv.writer(csvfile, dialect='excel') # 用csv.writer()函数创建一个writer对象。 header=['小区名称', '地址', '建筑年份', '楼栋', '单元', '户室', '朝向', '面积'] writer.writerow(header) title=input('请输入小区名称:') address = input('请输入小区地址:') year = input('请输入小区建造年份:') block = input('请输入楼栋号:') unit_loop = True while unit_loop: unit=input('请输入单元号:') start_floor = input('请输入起始楼层:') end_floor = input('请输入终止楼层:') # 开始输入模板数据 input('接下来请输入起始层每个房间的门牌号、南北朝向及面积,按任意键继续') start_floor_rooms = {} floor_last_number = [] # 收集起始层的房间信息 # 定义循环控制量 room_loop = True while room_loop: last_number = input('请输入起始楼层户室的尾号:(如01,02)') floor_last_number.append(last_number) #将尾号用append()添加列表里,如floor_last_number = ['01','02'] room_number = int(start_floor + last_number) #户室号为room_number,由楼层start_floor和尾号last_number组成,如301 direction = int(input('请输入 %d 的朝向(南北朝向输入1,东西朝向输入2):' % room_number )) area = int(input('请输入 %d 的面积,单位 ㎡ :' % room_number)) start_floor_rooms[room_number] = [direction,area] # 户室号为键,朝向和面积组成的列表为值,添加到字典里,如start_floor_rooms = {301:[1,70]} continued= input('是否需要输入下一个尾号?按 n 停止输入,按其他任意键继续:') #加入打破循环的条件 if continued == 'n': room_loop = False else: room_loop = True unit_rooms = {} #新建一个放单元所有户室数据的字典 unit_rooms[start_floor] = start_floor_rooms #unit_rooms={3:{301:[1,80],302:[1,80],303:[2,90],304:[2,90]}} for floor in range(int(start_floor) + 1, int(end_floor) + 1): #遍历除初始楼层外的其他楼层 floor_rooms = {} #每个楼层都建立一个字典 for i in range(len(start_floor_rooms)): #遍历每层有多少个房间,这里是3,即执行for i in range 3 的循环 number = str(floor) + floor_last_number[i] info = start_floor_rooms[int(start_floor + floor_last_number[i])] # 依次取出字典start_floor_rooms键对应的值,即面积和朝向组成的列表 floor_rooms[int(number)] = info #给字典floor_rooms添加键值对,floor_rooms = {401:[1,80]} unit_rooms[floor] = floor_rooms with open('data.csv', 'a', newline='')as csvfile: #Mac用户要加多一个参数 encoding = 'GBK' writer = csv.writer(csvfile, dialect='excel') for sub_dict in unit_rooms.values(): for room,info in sub_dict.items(): dire = ['', '南北', '东西'] writer.writerow([title,address,year,block,unit,room,dire[info[0]],info[1]]) unit_continue = input('是否需要输入下一个单元?按 n 停止单元输入,按其他任意键继续:') if unit_continue == 'n': unit_loop = False else: unit_loop = True print('恭喜你,信息录入工作完成!') ``` 来看一下运行后生成的excel吧!  这样就完成了一栋楼所有信息的录入,虽然中间要输入很多次信息,但程序的完成,为以后的录入减少了很多的工作量,同时也可以给别人使用,节省的时间远远大于付出的时间成本。快来试试吧! 文章部分图片及代码来源风变编程,我当时第一次看的时候有点懵,借此机会复习一遍,强化一下,不然很容易生疏,同时也分享给各位。<hr class="content-copyright" style="margin-top:50px" /><blockquote class="content-copyright" style="font-style:normal"><p class="content-copyright">版权属于:Erek</p><p class="content-copyright">本文链接:<a class="content-copyright" href="https://erek.top/archives/4.html">https://erek.top/archives/4.html</a></p><p class="content-copyright">转载时须注明出处及本声明</p></blockquote> 最后修改:2020 年 12 月 23 日 11 : 04 PM © 允许规范转载 赞赏 如果觉得我的文章对你有用,请随意赞赏 ×Close 赞赏作者 扫一扫支付 支付宝支付 微信支付
|´・ω・)ノ
yes