注:该学习笔记是根据曾志贤老师编写的《从Excel到Python,用Python轻松处理Excel数据》所学习整理的笔记。
第七章 字典类型处理技术
Python中字典的标准用法为{key:value,……}
- key(键):在字典中必须具有唯一性,且必须是不可变对象,如字符串、数字或元组。
- value(值):可以重复,也可以是任何数据类型,如字符串、元组、列表、集合等。
字典是无序的,只能通过键来存取对应的值,而不能像列表那样通过索引位置来存取对应的值。
目录
一、字典的基本操作
1、字典的创建与删除
dic=dict();print(dic) #返回 {}
dic2={};print(dic2) #返回 {}
dic3=dict(甲=11,乙=22);print(dic3) #返回 {'甲': 11, '乙': 22}
dic4={'丙':33,'丁':44};print(dic4) #返回 {'丙': 33, '丁': 44}
del dic4
print(dic4) #返回 错误
2、字典中key值的获取
dic={'甲':11,'乙':22,'丙':33,'丁':44}
print(dic['丙']) #获取 丙 对应的值 返回 33
print(dic.keys()) #获取所有的key 返回 ['甲', '乙', '丙', '丁']
print(dic.values()) #获取所有key的值 返回 [11, 22, 33, 44]
print(dic.items()) #获取所有的key和它的值 返回 [('甲', 11), ('乙', 22), ('丙', 33), ('丁', 44)]
二、字典key值的修改、增加、删除
1、字典key值的增加
向字典中增加更多的key值,一般使用update函数,也可以用修改key值的方式操作。
dic={}
dic.update(甲=11);print(dic)
dic.update({'乙':22});print(dic)
dic['丙']=33;print(dic) #修改指定key的值,如果指定的key不存在,则新增。
2、字典key值的删除
删除字典key值可以使用pop函数、clear函数、del语句。
dic={'甲':11,'乙':22,'丙':33,'丁':44}
dic.pop('甲');print(dic) #删除指定的key (可以保留值 赋给新key)
dic.clear();print(dic) #清空dic,但dic还是字典类型
del dic;print(dic) #删除整个dic对象
3、字典key值的修改
修改字典中key对应的值,表示方法为:字典名[key]=修改的值。
修改key没有直接的方法,可以使用间接的方式,表示方法为:字典名[新key]=字典.pop(旧key]
dic={'甲':11,'乙':22,'丙':33,'丁':44}
dic['甲']=55;print(dic) #修改 甲 的值
dic['乙2']=dic.pop('乙');print(dic) #删除 乙 并将乙的值赋给 乙2
案例一、提取指定内容
在“分数表”工作簿中的“分数表”工作表中获取每个班的最后一条记录,将结果写入新工作表中。
import xlrd
from xlutils.copy import copy
wb=xlrd.open_workbook('分数表.xls')
ws=wb.sheet_by_name('分数表')
nwb=copy(wb)
nws=nwb.add_sheet('处理后')
dic={}
row_num=0
#写法1
for num in range(1,ws.nrows):
key=ws.cell_value(num,0)
val=ws.cell_value(num,1)
dic[key]=val
for key1,val1 in dic.items():
nws.write(row_num,0,key1)
nws.write(row_num,1,val1)
row_num += 1
nwb.save('分数表-1.xls')
#写法2
for cls,name in ws.get_rows(): #读取所有行的值
dic[cls.value]=name.value
for key,item in dic.items():
nws.write(row_num,0,key)
nws.write(row_num,1,item)
row_num +=1
nwb.save('分数表-1.xls')
案例二、按姓名求总分数与平均分
在“分数”工作簿中的“分数表”工作表中,按照姓名求总分数与品骏分。
import xlrd
from xlutils.copy import copy
wb=xlrd.open_workbook('分数.xls')
ws=wb.sheet_by_name('分数表')
nwb=copy(wb)
nws=nwb.add_sheet('汇总表')
nws.write(0,0,'姓名')
nws.write(0,1,'总分')
nws.write(0,2,'平均分')
dic={}
row_num=0
for name,val in ws.get_rows():
if not name.value in dic:
dic[name.value]=[val.value]
else:
dic[name.value].append(val.value)
for key,item in tuple(dic.items())[1:]:
row_num +=1
nws.write(row_num,0,key)
nws.write(row_num,1,sum(item))
nws.write(row_num,2,'{:.2f}'.format(sum(item)/len(item)))
nwb.save('分数-1.xls')
三、字典的转换
字典的转换操作是指将列表、元组等可迭代对象的元素转换为对应的字典。
1、类对象转换dict
三种语法结构:
dict(**kwargs)
dict(mapping,**kwargs)
dict(iterable,**kwargs)
参数说明:
- **kwargs:关键字,采用“key=值”的方式创建字典。
- mapping:元素的容器,采用映射函数的方式创建字典。
- iterable:可迭代对象,采用可迭代对象的方式创建字典。
dic1=dict(a=1,b=2);print(dic1) #返回 {'a': 1, 'b': 2}
dic2=dict(zip(('a','b'),(1,2)));print(dic2) #返回 {'a': 1, 'b': 2}
dic3=dict([['a',1],['b',2]]);print(dic3) #返回 {'a': 1, 'b': 2}
2、dict.fromkeys 转换法
语法结构:
dict.fromkeys(sep[,valaue])
参数说明:
- sep:必选参数,字典的key,可以是元组、列表、字符串等可迭代对象。
- value:可选参数,设置key对应的值,默认为:None。
dic1=dict.fromkeys(('a','b'),1);print(dic1) #返回 {'a': 1, 'b': 1}
dic2=dict.fromkeys(('a','b'),[1,2]);print(dic2) #返回 {'a': [1, 2], 'b': [1, 2]}
dic3=dict.fromkeys('abc',1);print(dic3) #返回 {'a': 1, 'b': 1, 'c': 1}
dic4=dict.fromkeys(['a','a','b']);print(dic4) #返回 {'a': None, 'b': None}
dic5=dict.fromkeys([('a',1),('a',1)]);print(dic5) #返回 {('a', 1): None}
案例一、多列求唯一值
在“班级分数”工作簿中的“分数表”中,提取学校、年级、班级三列中的唯一值。
import xlrd
from xlutils.copy import copy
wb=xlrd.open_workbook('班级分数.xls')
ws=wb.sheet_by_name('分数表')
nwb=copy(wb)
nws=nwb.add_sheet('提取结果')
nws.write(0,0,'学校')
nws.write(0,1,'年级')
nws.write(0,2,'班级')
row_vals=()
num1 = 0
for num in range(1,ws.nrows):
v=ws.row_values(num)[0:3]
row_vals +=(tuple(v),) #将提取的值转换为元组,因为字典的key不支持可变对象列表类型。
for key in dict.fromkeys(row_vals): #使用fromkeys去重
num1 +=1
nws.write(num1,0,key[0])
nws.write(num1,1,key[1])
nws.write(num1,2,key[2])
nwb.save('班级分数-1.xls')
四、字典综合应用案例
案例一、获取未完成名单
在“名单”工作簿中,根据“全部名单”工作表和“已完成名单”工作表来判断哪些人是未完成工作的,并写入“未完成名单”工作表。
import xlrd
from xlutils.copy import copy
wb=xlrd.open_workbook('名单.xls')
ws1=wb.sheet_by_name('全部名单')
ws2=wb.sheet_by_name('已完成名单')
nwb=copy(wb)
nws=nwb.get_sheet('未完成名单')
dic,row_vals,num1={},(),0
for name1,dept1 in ws1.get_rows():
dic[name1.value]=dept1.value #将“全部名单”放入字典
for num in range(1,ws2.nrows):
v=ws2.row_values(num)
row_vals +=(tuple(v),) #将“已完成名单”放入元组
for name2,dept2 in row_vals:
del dic[name2] #以“已完成名单”为循环,删除对应字典的key
for val in dic.items():
nws.write(num1,0,val[0])
nws.write(num1,1,val[1])
num1 +=1
nwb.save('名单-1.xls')
案例二、多工作簿数据合并
案例要求:将多个工作簿中的多个工作表数据合并到同一个表格中。效果如下图所示:
import os,xlrd,xlwt
nwb=xlwt.Workbook('utf-8')
nws=nwb.add_sheet('合并汇总')
files=os.listdir('销售表') #获取该文件夹下所有工作簿名称
nws.write(0,0,'店名')
nws.write(0,1,'品牌')
nws.write(0,2,'型号')
nws.write(0,3,'数量')
row_num=0
for file in files: #循环所有工作簿名称
wb=xlrd.open_workbook('销售表/'+file) #打开循环的工作簿
for ws in wb.sheets(): #循环所有工作表
for i,j in tuple(ws.get_rows())[1:]: #循环所有行的值
tup=(file.split('.')[0],ws.name,i.value,j.value) #重新组合
row_num +=1
for k in range(0,4): #建立列循环
nws.write(row_num,k,tup[k]) #写入值
nwb.save('销售表汇总.xls')
案例三、数据统计并分发至不同工作簿
案例要求:将一张表中的数据执行统计,将分发到不同工作簿。处理效果所下所示:
import xlrd,xlwt
ws=xlrd.open_workbook('统计.xls').sheet_by_name('业绩表')
dic={}
for row_num in range(1,ws.nrows):
lst=ws.row_values(row_num) #读取数据到列表
key=(lst[0],lst[1]) #把A和B列组合起来作为字典的key
if not key in dic: #判断字典是否存在key
dic[key]=[lst[4]] #不存在则给key赋值
else:
dic[key].append(lst[4]) #存在则将值放入值的列表中
for i in dict.fromkeys(tuple(zip(*dic.keys()))[0]): #循环字典中key的A列 省份
nwb=xlwt.Workbook('utf-8')
nws=nwb.add_sheet('province') #以省份名新建工作表
num=0
nws.write(num,0,'公司名')
nws.write(num,1,'交易次数')
nws.write(num,2,'总金额')
for j,k in dic.items(): #将字典的key和值分别带入循环
if j[0]==i: #判断key的省份是否等于 省份循环的值
for l in [(j[1],k)]: #将符合条件的key的公司名,与值带入循环
num +=1
nws.write(num,0,l[0]) #写入公司名
nws.write(num,1,len(l[1])) #写入交易次数
nws.write(num,2,sum(l[1])) #写入总金额
nwb.save('统计结果/'+i+'.xls') #按照循环的省份保存在指定文件夹内