Python 作为一门成熟的语言 功能很全面 且具有大量的第三方库。库指的是别人已经写好的代码 用户可以直接调用。因此 学习Python的周期会比较长 这就导致学习者 比如 我 感觉自己会的东西很少 还不足以解决实际问题。在这种认知下 不断的学习 但是 总是学不完 由此 产生了一丝焦虑感。在意识到这一问题后 我开始思索就目前已经学习的知识可以帮助我解决哪些实际问题。
利用openpyxl 解决的第一个实际问题我的实际需求就是把第一张图中的数据转化为第二张图中的数据。
第一张照片
第二张照片
艰难的编码过程 将range()函数的用法与列表切片的方式相混合
由于需要对Excel 表格多行和多列进行操作 因此 需要进行循环操作。我写的前几行代码如下
import openpyxl f openpyxl.load_workbook( 1.xlsx ) sheet1 f.active for i in range(1:51): 输出
根据输出的指示 我误以为是因为我在中文状态下输入了冒号 因此 会报错。在确定确实在英文状态输入的冒号后 我怀疑是不是输入法有问题 于是 我换了另一个输入法 结果还是报错。我想可能是Python解释器出现了问题 于是 我安装了最新版的解释器 但是 问题依然存在。那时 我想可能是系统坏了 现在回想起来 这是多么疯狂的想法 但是 当时就是这么想的 。还好装系统比较麻烦 我没有采取这步行动。在压抑之中 我看了一部电影放松了一下。看完电影后 我突然发现range()函数的上下界是用英文状态下的逗号连接 而不是用冒号连接。这在心理学上称之为酝酿效应。酝酿效应指的是在长期思考某一问题而又百思不得其解时 如果停下对这个问题思考去做别的事情 过一顿时间后 可能会突然想到解决问题的办法。这听起来好像有点玄学的感觉。其本质原因是因为 我们在一条行不通的道路上 越陷越深。这时候 如果停下来 做其它的事情 当我们再回头看这个未解决的问题时 我们可能会意识到自己选择了一条错误解决问题的路径。
在发现问题后 我意识到我是将列表切片的操作方式与range()函数的上下界方式搞混淆了。
编码过程 注意事项用openpyxl 进行数据写出的时候 一定要注意复制原始数据。当然 也可以将数据写出到一个新的Excel表格中。
以一列的一个条件为基础 检查代码的运行效果在第一行代码中 我们导入了openpyxl 库 在第二行代码中 我们加载了名字为‘1’ 文件拓展名为‘xlsx 的Excel表格 在第二行代码中 我们调用了表格的活动工作表 即上一次关闭软件前 保存的工作表。
在第四行代码中 我们使用了一个for 循环 在第五行代码中 我们使用了一个if 条件从句 判断第一行第一列 i 第一次进入for 循环 的值是否小于20 如果小于20 那么 将该值改为1。
import openpyxl f openpyxl.load_workbook( 1.xlsx ) sheet1 f.active for i in range(1,51): if sheet1.cell(row i,column 1).value 20: sheet1.cell(row i,column 1).value 1 f.save( 1.xlsx )以一列的所有条件为基础 检查代码的运行效果
在确定第一个条件运行成功后 接下来 就是补全其它的条件 看看第一列的整体运行结果 是不是和预期一样。
import openpyxl f openpyxl.load_workbook( 1.xlsx ) sheet1 f.active for i in range(1,51): if sheet1.cell(row i,column 1).value 20: sheet1.cell(row i,column 1).value 1 elif sheet1.cell(row i,column 1).value 40: sheet1.cell(row i,column 1).value 2 elif sheet1.cell(row i,column 1).value 60: sheet1.cell(row i,column 1).value 3 elif sheet1.cell(row i,column 1).value 80: sheet1.cell(row i,column 1).value 4 elif sheet1.cell(row i,column 1).value 100: sheet1.cell(row i,column 1).value 5 f.save( 1.xlsx )对整个表格进行操作
在解决了一列的问题后 我们需要另一个for循环 使得所有的列都能得到遍历。通过观察 我们发现 需要改变的行的数据在1,3 5,7 等。因此 我们可以给for 循环加第三个参数 即步幅 来解决这一问题。
import openpyxl f openpyxl.load_workbook( 1.xlsx ) sheet1 f.active for i in range(1,51): for j in range(1,43,2): if sheet1.cell(row i,column j).value 20: sheet1.cell(row i,column j).value 1 elif sheet1.cell(row i,column j).value 40: sheet1.cell(row i,column j).value 2 elif sheet1.cell(row i,column j).value 60: sheet1.cell(row i,column j).value 3 elif sheet1.cell(row i,column j).value 80: sheet1.cell(row i,column j).value 4 elif sheet1.cell(row i,column j).value 100: sheet1.cell(row i,column j).value 5 f.save( 1.xlsx )
到这里问题就得到解决了。
迁移到其它场景读者可能会想这个操作可以迁移到其它类似的场合吗 答案是肯定。比如 教育部规定小学阶段只能以等级的方式 呈现学生的成绩。但是 在实际阅卷的过程中 教师需要先打出具体的分数 然后 再转化为相应的等级。在这种情况下 就可以完全借鉴上一段代码的思路。
能运行的代码就是好的代码作为学习者 不需要在开始学习的阶段 对自己所写的代码 要求过高。因为代码的使用者是自己 所以只要代码能够达到预期的目标就是好的代码。当然 后续随着学习更多的知识 可以对现有的代码进行完善。比如 在我的这段代码中 由于我知道数据有多少行、多少列 所以 我直接填入了数字。如果不知道表格有多少行或多少列 就需要对代码进行改进了。当然 还是可以通过数的方式获得具体的行列数 只是容易出错 且耗时。
import openpyxl f openpyxl.load_workbook( 1.xlsx ) sheet1 f.active for i in range(1,sheet1.max_row 1): for j in range(1,sheet1.max_column 1,2): if sheet1.cell(row i,column j).value 20: sheet1.cell(row i,column j).value 1 elif sheet1.cell(row i,column j).value 40: sheet1.cell(row i,column j).value 2 elif sheet1.cell(row i,column j).value 60: sheet1.cell(row i,column j).value 3 elif sheet1.cell(row i,column j).value 80: sheet1.cell(row i,column j).value 4 elif sheet1.cell(row i,column j).value 100: sheet1.cell(row i,column j).value 5 f.save( 1.xlsx )
需要注意range()函数是左开右闭 所以 需要在最大行列数的基础上加1 才能获得所有的行列数的数据。



