零基础学习Python第21课:字符串合并与拆分

职场   2024-11-13 12:05   福建  

HI,大家好,我是星光。

通过前面章节的学习,相信你已经掌握了一部分字符串合并的技巧。例如,使用运算符'+'可以将多个字符串合并为一个新字符串:

s =  '1班' + '看见星光'

当被合并的对象的类型是非字符串时,还需要使用str等函数转换处理,以下代码将字符串'看见星光'和数字59合并为字符串:'看见星光59':

s = '看见星光' + str(59)

运算符"+"常用于少量字符串的合并,当被合并的字符串比较多时,这种方法就偏于烦琐了,此时更推荐使用join()方法。


1 丨 join()方法


字符串的join()方法可以将序列中的元素以指定的分隔符连接成一个新的字符串,基本语法如下:


str.join(iterable)

str是指定的分隔符,iterable是一个可迭代对象,其元素必须为字符串,如果其中包含了非字符串,会导致代码抛出异常:TypeError。


举几个小栗子。


以下代码将列表r中的元素合并为一个字符串:"一班男看见星光"


r =  ['一班','男','看见星光']"".join(r)


代码中join方法指定间隔符为空值,因此合并后的字符串实际上并不存在间隔符。


以下代码使用间隔符"-"将列表r中的元素合并为"一班-男-见星光"。代码中join方法指定了间隔符为小横杠。


r =  ['一班','男','看见星光']"-".join(r)

以下代码列表r中存在非字符串元素,代码运行后join方法会抛出异常。


r =  ['一班','男','看见星光',59]"-".join(r)

如何避免可迭代对象中存在非字符串元素导致join合并失败呢?例如,将以上代码中列表r的元素合并,返回所需结果为:"一班-男-见星光-59"


 ̄︶ ̄)↗ 

——这是本期的第1个练习题(


……


本期的案例工作簿中「文件下载见知识星球」有一个名称为'示例1'的工作表,内容如下图所示,其中C~F列为各科成绩,需要在G列查询成绩大于90分的科目名称



打开VSCode,创建一个代码单元格,输入并运行以下代码,自动打开目标工作簿。


import xlwings as xw # 导入xlwingsapp = xw.App(visible=True, add_book=False) # 创建一个Excel实例path = r"文件全路径" #文件路径wb = app.books.open(path)sht = wb.sheets['示例1'# 选择工作表


新建一个代码单元格,输入并运行以下代码:


arr = sht.range('c1:f1').expand('down').value # 获取数据aTit,aRes = arr.pop(0),[]for r in arr:    aRes.append(["-".join([x for x,y in zip(aTit,r) if y>90])])sht.range('g2').value = aRes

第2行代码声明了两个列表变量,其中aTit内容为列表arr弹出的第1个元素,也就是标题行,aRes是一个空列表,用于保存计算结果。


第3~4行代码遍历列表arr每一行数据(此时arr已经将标题行pop弹掉了,只剩下了数据行)。


其中第3行代码先使用zip函数将标题列表aTit和数据列表r横向合并成可迭代对象: zip(aTit,r)。合并后的元组为4行2列结构:



然后使用列表推导式遍历每行元素,推导式包含了2个循环变量:x和y,x指向标题元素,y指向成绩元素,列表推导式使用if子句筛选成绩大于90的科目名称。


[x for x,y in zip(aTit,r) if y>90]


最后再使用join函数将符合条件的科目合并成一个字符串,追加写入结果列表aRes。


……



2 丨 split()方法



啪!众所周知,天下大势合久必分分久必合,天下兴亡匹夫有责,谈了恋爱就想结婚,结了婚就想离婚……咳,同样的道理,字符串这个家伙,有合也有分。


split() 是最常用的字符串拆分方法,它可以将字符串按照指定的分隔符拆分成多个子字符串,并返回一个列表,基本语法如下:


str.split(sep=None, maxsplit=-1)

str是被拆分的字符串,参数sep指定分隔符,默认为所有的空白字符(空格、制表符、换行符等),参数maxsplit指定最多拆分的次数,默认为 -1,表示不限制拆分次数。


照例举几个简单的小栗子。


以下代码将字符串'看见星光 语文 99'拆成列表['看见星光', '语文', '99'],split方法省略了所有参数,表示按空白字符(空格、制表符、换行符等)应拆尽拆。


'看见星光 语文 99'.split()

以下代码将字符串'看见星光-语文-99'拆成列表['看见星光', '语文', '99'],其中split方法的将分隔符设置为小横杠,第2参数省略,表示应拆尽拆。


'看见星光-语文-99'.split('-')

以下代码将字符串'看见星光-语文-99'拆成列表['看见星光', '语文-99'],其中split方法的将分隔符设置为小横杠,第2参数设置为1,表示只拆首个小横杠。


'看见星光-语文-99'.split('-',1)

……


本期案例工作簿中有一个名称为'示例2'的工作表,内容如下图所示。其中A列是混合数据,需要按分隔符小横杠,拆分成如C:H列所示的表格。


参考代码如下:


sht = wb.sheets['示例2'] # 选择工作表lst = sht.range('a1').expand('down').valueaRes = [s.split('-') for s in lst]sht.range('c1').value = aRes

第1~2行代码读取A列数据,赋值变量lst。第3行代码使用列表推导式遍历列表lst,使用split()方法将元素按小横杠拆分。


打个响指,还是同样的数据源,需要将其转换为一维表的结构,模拟结果如下图C~F列所示。


摊手,这是本期的第2道练习题。


……

……

用涂改液擦拭屏幕可以看到参考答案▼

¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥


PS:


记得把本章代码实操一遍:打开VSCode→新建文件→设置环境→复制输入代码→运行,有问题随时在VIP会员微信答疑群中提问交流,行动力是最重要的学习能力没有之一。


……


……


题2参考解法如下----
建议先思考后对照,纸上得来终觉浅,只看不练假把戏
( •̀ ω •́ )✧):


sht = wb.sheets['示例2'] # 选择工作表lst = sht.range('a1').expand('down').valueaTit = lst.pop(0).split('-')[2:] #标题列表aRes = [] #结果列表for row in lst:    r = row.split('-') #分割    for x,y in zip(aTit,r[2:]): #zip将标题和数据对应        aRes.append(r[:2] + [x,y]) #将班级姓名科目和成绩 写入结果列表sht.range('c1').value = [['班级','姓名','科目','成绩']] + aRes  

代码用了2个for循环语句,第1个for循环遍历每行数据,第2个for循环使用zip函数将科目和成绩横向合并,再将两者逐行取出,和r[:2]的班级、姓名,追加写入结果列表aRes——这里使用的是本节教程案例1的套路。


其中第2个for循环可以压缩成列表推导式。下面这段代码你还需要思考为什么使用的是aRes+=.... 而不是aRes.append()▼


aRes = [] #结果列表for row in lst:    r = row.split('-') #分割    aRes += [r[:2] + [x,y] for x,y in zip(aTit,r[2:])]


同样的道理,第1个for循环其实也可以压缩成列表推导式:


aRes = [    row.split('-')[:2] + [x, y]    for row in lst    for x, y in zip(aTit, row.split('-')[2:])]

又或者压缩成如下推导式:


aRes = [    r[:2] + [x, y]    for row in lst    for r in [row.split('-')]    for x, y in zip(aTit, r[2:])]


……

……


下期再见。



🔽点击阅读原文
从0到1系统学习Python

Excel星球
微软全球最有价值专家(Excel MVP),上千篇原创图文和视频教程随学随用,随用随查,建议常用Excel的职场人关注。
 最新文章