上一篇回顾
上一关中,我们重识了 字符串,还了解了 字符串拼接 和 字符串格式化输出 的方法。
字符串的“乘法”可以很方便地“复读”字符串,让字符串与一个整数 n 相乘,字符串就会原样复制 n 次。
在体验课中我们学到,要想让数字与字符串拼接起来,就要先用 str()
函数进行类型转换,这实在有点麻烦。学完上一关后,你就知道该怎么走捷径了。
占位符 在字符串中先占上几个“坑”,我们将需要“填坑”的内容写到 元组 中,跟在 %
后面,Python 就会将这些内容依次填到占位符所在的位置。
今天我们要继续深入一些更高级的字符串操作方法,咱们一起探索吧!
字符串索引
在学列表的时候,我们知道了可以通过 索引 来访问列表里的元素,其实字符串也一样有 索引。
和列表一样,我们可以通过索引或反向索引的方式访问字符串中的字符:
str = 'Hello World'
print(str[6]) # 输出:W
print(str[-5]) # 输出:W
字符串索引的原理和列表索引的原理是一样的。
正向索引是从 0 开始计数,而反向索引则是从 -1 开始计数,这一点一定要记清楚。
一般我们采取“就近原则”来决定使用正向索引还是反向索引——即访问靠前的元素用正向索引,靠后的元素用反向索引,这样就可以尽可能少地数这是第几个元素了。
编程练习
《水浒传》中,宋江为了将卢俊义逼上梁山,军师吴用巧施一计,他扮成一个算命先生,来到卢俊义庄上,口占四句卦歌,并端书在卢宅的墙壁上,巧妙地把“卢俊义反”四个字暗藏于四句之首。之后,官府拿到了证据,到处捉拿卢俊义,终于把他逼上梁山。
请你用字符串索引的知识,将这首藏头诗每一句的第一个字拼在一起,并在屏幕上打印出来。
str1 = "芦花丛中一扁舟"
str2 = "俊杰俄从此地游"
str3 = "义士若能知此理"
str4 = "反躬难逃可无忧"
print(str1 + str2 + str3 + str4)
解答后为:
str1 = "芦花丛中一扁舟"
str2 = "俊杰俄从此地游"
str3 = "义士若能知此理"
str4 = "反躬难逃可无忧"
print(str1[0] + str2[0] + str3[0] + str4[0])
# 输出为:卢俊义反
字符串分片
除了索引之外,字符串和列表还有很多相似之处:它们都是有序序列,都可以使用 len() 函数获取元素个数,当然还有本节的重点——分片。
字符串的分片和列表的分片是一样的,我们直接来看个字符串分片的例子:
str = 'Hello World'
# 下面两个效果一样
print(str[6:]) # 输出:World
print(str[-5:]) # 输出:World
字符串分片同样也可以用正向索引和反向索引,它俩的效果一样。
我们通过一些例子来回忆一下之前说过的分片操作:
string = 'Hello World'
# 从索引 0 开始,到索引 3 为止,不包括索引 3
print(string[0:3])
# 输出:Hel
# 如果第一个索引是 0,可以省略
print(string[:3])
# 输出:Hel
print(string[3:11])
# 输出:lo World
# 如果分片到末尾,后面也可以省略
print(string[3:])
# 输出:lo World
# 如果都省略,则是复制一个一样的字符串
print(string[:])
# 输出:Hello World
上面的这些例子中有两个注意点:
1、分片是半闭半开区间,即包含前面索引位置的元素,不包含后面索引位置的元素。比如:string[m:n] 获取的是字符串 string 中索引为 m 到 n-1 之间的元素(包括 m 和 n-1);
2、分片中前后索引的值是可以省略的,前索引省略默认为 0,后索引省略默认为序列长度。
你可能会有疑问:分片包含前面索引位置的元素却不包含后面索引位置的元素,为什么不都包含或都不包含呢?这样不是更好记吗?
举个例子你就明白了:有个字符串 string 的值为 'Hello World',我们假设分片两个索引位置的元素是都包含的,这时要用分片获取 string 前三个元素则应写作 string[:2]。
同样是获取索引为 0、1、2 的三个元素,不包含后面索引位置的元素写作 string[:3]。不包含后面索引位置元素的写法是不是更符合直觉?
获取前三个元素写作 string[:3],获取后三个元素写作 string[-3:]。正向索引常用于获取靠前的元素,反向索引常用于获取靠后的元素。这两个例子是不是很清晰地展现了正向索引和反向索引的适用场景?
关于分片我最后还想再讲一个小知识点,我们先来看段代码,你猜猜运行结果是什么:
string = 'Hello World'
print(string[0:100000])
答案是:Hello World。有些同学可能认为上面代码会报错,因为后面索引超出了字符串本身的长度。
其实不然,分片超出范围是不会报错的。你可以把字符串想象成一根绳子,分片就是用刀将绳子切分开来。在字符串长度内分片相当于在绳子上切割,而超出范围相当于一刀砍到了空气,对于绳子来说没有影响。
注意!这一点和索引取值是不同的,如果索引取值超出范围将会报错。比如将上面的第二行代码改成 print(string[100000]) 将会得到 IndexError: string index out of range(索引错误:字符串索引超出范围)的报错。
稍稍剧透一下,本关的上机作业将会用到这个知识点,到时候不要忘记哦~
提示:上述字符串分片的知识对列表、元组分片同样适用。
编程练习
小贝去菜市场买菜,她选中了一块猪肉,但是肥瘦相间。小贝只想要中间的瘦肉,你能帮她“切出瘦肉”吗?
pork = '瘦肉肥肉瘦肉瘦肉瘦肉肥肉肥肉瘦肉肥肉'
切片后:
pork = '瘦肉肥肉瘦肉瘦肉瘦肉肥肉肥肉瘦肉肥肉'
# 要“切出”中间的“瘦肉瘦肉瘦肉”哦
print(pork[4:-8])
字符串不可变性
在讲列表中的索引时,我们说过可以通过索引来改变列表中元素的内容,比如:
names = ['鲁班七号', '蔡文姬', '甄姬', '亚瑟', '兰陵王']
names[0] = '后裔'
print(names)
# 输出:['后裔', '蔡文姬', '甄姬', '亚瑟', '兰陵王']
但字符串一旦创建后是不可改变的,这个属性和元组类似,通过索引来改变字符串中元素就会报错:
name = '鹿班七号'
name[0] = '鲁'
print(name)
# 报错:TypeError: 'str' does not support item assignment on line 2
那么我们怎样才能修改字符串的内容呢?答案是使用字符串分片和拼接去生成一个新的字符串,看个例子:
name = '鹿班七号'
new_name = '鲁' + name[1:]
print(new_name)
# 输出:鲁班七号
编程练习
古代诗词讲究押韵,现代的说唱也讲究单押、双押等。自挂东南枝 和很多别的诗句搭配读起来也朗朗上口,十分押韵。
我们来试试将 空山新雨后,天气晚来秋。 的前半句和 徘徊庭树下,自挂东南枝。 的后半句结合起来,打印出来读读看吧!
poetry1 = '空山新雨后,天气晚来秋。'
poetry2 = '徘徊庭树下,自挂东南枝。'
print(poetry1[:6] + poetry2[6:])
# 输出为:空山新雨后,自挂东南枝。
讨厌的错别字
小贝正在做语文作业,但她一个不注意,把“关羽”错写成“项羽”了。
你能结合 for
循环和字符串方法,将 homework
中的 项羽 全部改正为 关羽 吗?
homework = '''提起刘备、项羽和张飞,人们总是会联想到桃园三结义的故事。
东汉末年,朝廷腐败,民不聊生。
刘备、项羽和张飞想共同干一番事业,拯救陷入水深火热之中的百姓。
三人在桃园结为异姓兄弟,风雨同舟,肝胆相照,开创了蜀汉基业。'''
# 请补充代码
print(homework)
补充后的代码为:
homework = '''提起刘备、项羽和张飞,人们总是会联想到桃园三结义的故事。
东汉末年,朝廷腐败,民不聊生。
刘备、项羽和张飞想共同干一番事业,拯救陷入水深火热之中的百姓。
三人在桃园结为异姓兄弟,风雨同舟,肝胆相照,开创了蜀汉基业。'''
for i in range(len(homework)):
if homework[i:i+2] == '项羽':
homework = homework[:i] + '关羽' + homework[i+2:]
print(homework)
下集预告:
Python 中内置了很多实用的字符串方法,能够让你用一行代码搞定各种复杂的难题。
英文字母大小写互换,自由分割与拼合,查找指定字符串……你想怎么做,Python 都能满足你。
除了实用的内置方法外,我们还会接触到一种新的 格式化输出方法,之前学过的占位符和新方法比起来,哪个更方便呢?学了就知道!