我们对“字符串”这个词语已经不陌生了。字符串由数字、字母、下划线、汉字等组成,是非常常用的数据类型,甚至在你意识不到的时候,就一直在使用字符串了。比如,你使用input函数从终端得到的输入全部都是字符串。虽然我们已经多次使用了字符串,但是字符串中还有很多你不知道的秘密,这一节,让我们重新认识字符串。
一、课程回顾
正式学习字符串之前我们先来回顾一下上节最后的作业。 上一节课的课后作业是计算成绩的总分和平均值,按格式输出。参考代码如下:
name = input('请输入姓名:')
a1 = float(input('请输入语文成绩:'))
a2 = float(input('请输入数学成绩:'))
a3 = float(input('请输入英语成绩:'))
print('姓名 语文 数学 英语 总分 平均')
print(name,' ',a1,' ',a2,' ',a3,' ',round(a1+a2+a3,2),' ',round((a1+a2+a3)/3,2))
可以看出,我们计算的代码没有多少,反而最后用print函数输出的时候写了很长一行指令,为了让输出的数据对齐,我们使用输出一个变量再加四个空格的方式,感觉挺麻烦的。有没有简单一点的方法呢?学完本节内容,相信你会有答案。
二、字符串的表示
目前为止,我们知道,字符串用单引号或双引号来“包括”它的内容(这里的引号都是英文状态下的引号)。比如"hello,world"
和'hello,world'
表达的含义是一样的。但是这两种方式一般只用于单行的字符串,如果你的字符串很长,比如是一篇文章,里面有很多句子,还需要分段,用它就不行了。所以Python还提供了一种更灵活的方式,用三个单引号或双引号来包括字符,形成字符串。比如下面这段代码:
# 用三个单引号或双引号表示多行字符串
s1 = '''
白日依山尽,
黄河入海流。
欲穷千里目,
更上一层楼。
'''
print(s1)
程序输出如下:
这里我是用了三个单引号表示字符串,你换成三个双引号也没有问题。三个引号中间的内容你随便输入都可以,但是不能出现连续的三个引号,那样就破坏了字符串的完整性,python不知道你的字符串是从哪开始到哪结束的了。
使用三引号,甚至可以输出一些有趣的字符图形,比如:
s1 = '''
__----_
/##| \
/###| | \___
|####| \
|####| |©
\####/ _____ /
\### /
=====ÊšçØ
/ \
| |_ \
\___/ |
=\ /
_| |__|__
(______)___)ƨ‹
'''
print(s1)
三引号内的字符串是按原样输出的,所以Python会在终端给你打印一只“小狗”出来。
关于字符串的表示还有一个重要概念是转义字符。在Python中,把具有特殊含义的符号(如引号、反斜杠 \ )或其它不能通过键盘输入的字符以反斜杠“\”开头的字符序列表示,这称为转义字符。
什么意思呢?就是字符串是用引号包括起来的,如果你的字符串中本身就有引号怎么办?引号本身是用来包括字符串的,你如果中间插入一个引号,后半段字符串不就失去了引号包括了吗?这时我们就得使用转义字符来表示字符串中出现的引号。同理,反斜杠用来表示转义,那如果你字符串中出现了反斜杠,你就得用两个反斜杠来表示这里要输出反斜杠而不是转义。
常用的转义字符包括:
转义字符 | 含义 |
---|---|
\’ | 单引号 |
\” | 双引号 |
\ \ | 反斜杠 |
\r | 回车符 |
\n | 换行符 |
\t | 制表符 |
这个说起来挺抽象的,我们举例说明:
s1 = ' python 使用反斜杠“\\”对字符进行转义,\n 例如换行使用转义字符 \\n来表示'
print(s1)
程序输出是这样的:
我们看到,第一处转义是用“\”输出了“\”,第二处是“\n”,它把字符串分成了两行;第三处是用“\n”表示了“\n”,要不它就成了换行符。
关于转义字符,以后我们在使用字符串时用得多了,你自然就掌握了,这里先了解一下。
三、字符串的运算
上次我们做数据运算的时候无意中发现,字符串居然可以乘数字,结果是把字符串重复若干次。其实,字符串还支持下面的运算符:
我们假设a = ‘hello’,b=’python’:
运算符 | 描述 | 举例 |
---|---|---|
+ | 字符串连接,就是Scratch中的【连接“苹果”和“香蕉”】 指令 | a + b得到’hello python’ |
* | 重复输出字符串 | a * 3 得到 ‘hellohellohello’ |
[ ] | 通过索引获取字符串中的字符 | a[0]==’h’、a[1] == ‘e’、a[-1] == ‘o’ |
[ : ] | 截取字符串的一部分遵循左闭右开原则 | a[0:3] == ‘hel’ |
in | 成员运算符,如果字符串包括给定字符返回True,否则返回False | ‘h’ in a == True |
not in | 成员运算符,如果字符串不包括给定字符返回True,否则返回False | ‘h’ not in a == False |
字符串加法和乘法包括成员运算符都很好理解,这里重点讲索引和截取。
索引
字符串的索引是指字符串中每个字符对应的位置标号,通过索引可以获取字符串中的单个字符。索引分为正向索引和反向索引。正向从0开始,反向从-1开始,且索引值必须为整数。以字符串“Python”为例,每个字符的索引看下面这个表:
索引 | P | Y | T | H | O | N |
---|---|---|---|---|---|---|
正向 | 0 | 1 | 2 | 3 | 4 | 5 |
负向 | -6 | -5 | -4 | -3 | -2 | -1 |
所以,如果要访问最后一个字符n,你可以用[5],也可以用[-1]。
切片
在编程中经常会遇到需要截取字符串中某些部分的情况,切片就是为了实现这个目标而设计的,它可以通过索引来截取字符串中指定区间内的子字符串。切片的格式为:
# 切片格式
s1 = 'hello python!'
# s1[ start : end : step]
- start是起始索引,取值时包括该索引,如果省略start,则代表从0开始
- end是结束索引,取值时不包含该索引,如果省略end,则代表到字符串末尾结束
- step 是步长,即每step个字符取出一个,如果省略,代表是1
我们举例说明:
s1 = 'hello python!'
print(s1[6:12]) # 打印Python
print(s1[6:-1]) # 还是打印Python
print(s1[-7:-1]) # 仍然打印Python
print(s1[:5]) # 省略了start,从0开始,输出 hello
print(s1[6:]) # 省略了end,截取到末尾,输出python!
print(s1[::-1]) # 猜猜会输出什么?
最后一个比较特殊,它输出了:!nohtyp olleh 乍一看是乱七八糟,其实,它是把’hello python!’反过来写了一遍,实现了逆序输出。为什么是这样呢?首先,这里的start和end都省略了,表示从头到尾,但是step为-1,表示倒序截取,每次截取一个字符,这种情况下就会把字符串逆序输出。如果你要判断一个字符串是不是“回文”(即正着写反着写都一样),就可以用这种方法了。
注意事项:
- 使用+号连接字符串,中间连接处不会有任何间隔字符
- 字符串只能与整数进行乘法运算,如果乘以0或者负整数,会得到空字符串
- 正向索引第一个字符索引为0,反向索引第一个字符索引为-1
- 切片遵循左闭右开原则,例如 s1[0:2]不包括第三个字符。
四、字符串的常用方法
字符串常用的方法如下:
方法与函数 | 描述 |
---|---|
count() | 统计子字符串在字符串中出现的次数 |
find() | 检索子字符串在字符串中的索引位置 |
join() | 将序列中的元素以指定的字符连接成一个新的字符串 |
split() | 指定分隔字符串对字符串进行拆分,将拆分的结果以列表形式返回 |
len() | 统计字符串中字符个数,即字符串长度 |
lower() | 将字符串全部改为小写字母 |
upper() | 将字符串全部改为大写字母 |
title() | 将字符串中的每个单词的首字母改为大写 |
1、count()方法
count()方法的格式是:str.count(sub, start, end) – str为字符串 – sub 是要统计的子字符串 – start 查找的开始索引,如果省略表示从字符串开头开始; – end 查找的结束索引(不包括结束索引),如果省略结束索引表示到字符串末尾
例如:
s1 = 'hello, python!'
sub = 'o'
print(s1.count(sub)) # 返回2,出现2次o
print(s1.count(sub,0,5)) # 返回1,因为它只截取到第一个o,5是“,”索引,不包括在统计范围。
2、find()方法
find()方法用于检查子字符串在字符串中位置,如果在指定范围内找到,返回最小索引值,否则返回 -1。 find()方法格式如下:
str.find(sub, start, end) – str:字符串 – sub:子字符串 – start:搜索范围的开始索引,如果省略则表示从头开始 – end:搜索范围的结束索引,如果省略表示搜索到结尾
例如:
s = 'hello python!'
sub = 'python'
print(s.find(sub)) # 找到,返回6,即p位置的索引
3、join()方法
join()方法用于将可迭代对象中的元素以指定的字符串作为分隔符连接生成新的字符串,这里的“可迭代对象”只能包含字符串类型的元素。
join()方法的格式: str.join( iterable ) – str 用来分隔可迭代对象的字符串 – iterable 可迭代对象,就是可以循环遍历的对象,比如字符串和列表
例如:
s1 = ','
s2 = 'abcdefghijklmnopqrstuvwxyz'
print(s1.join(s2)) # 会打印a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z
4、split()方法
用指定的分隔符拆分字符串,返回列表。 split()方法的格式: str.split(sep, maxsplit=-1) – str:要分隔的字符串 – sep:分隔符,如果不指定,会把全部空字符作为分隔符,如包括空格、换行(\n)、制表符(\t)等 – maxsplit:最多拆分次数,默认为-1,表示不限制拆分次数
例如:
s1 = 'hello, python!'
print(s1.split(',')) # 返回一个列表:['hello', ' python!']
5、len()函数
len是python的内置函数,可用来计算字符串长度,也可以计算列表、元组的元素个数。 len()函数的格式:len(str)
s1 = 'hello,python!'
print(len(s1)) # 返回13
6、upper()、lower() 和title()
这几个方法非常简单,直接看例子:
s1 = 'Hello, python!'
print(s1.title()) # 打印 Hello, Python!
print(s1.lower()) # 打印 hello, python!
print(s1.upper()) # 打印 HELLO, PYTHON!
五、字符串格式化
最后我们来聊聊字符串的格式化。字符串格式化也称为字符串的插值运算,是指把一个值插入到另一个含有转换标记“%”的字符串中,“%”用于在字符串中标记转换符的位置,待插入的数据放在一个序列中。
格式符 | 描述 |
---|---|
%s | 格式化字符串 |
%d | 格式化十进制整数 |
%f | 格式化十进制浮点数 |
print函数可以使用格式化转换符号“%”对各种类型的数据进行格式化输出,写法是: print(‘包括格式符的字符串’%(a1,a2,a3,…,an),其中如果字符串中包括的格式符是整数或字符串,直接写%d或%s,如果是浮点数%f,还可以设置输出精度,比如print(‘ %.nf ‘%(a,))表示保留n位小数。
我们还是举例说明吧:
a = 5
print("a的整数形式:%d,a的浮点数形式: %.4f"%(a,a)) # 输出 a的整数形式:5,a的浮点数形式: 5.0000
这里对同一个数字5,我们如果用整数格式化输出是5,用4位浮点数格式化输出则是5.0000。看到这里,你是不是明白怎么修改上一节课的程序了呢?
name = input('请输入姓名:')
a1 = float(input('请输入语文成绩:'))
a2 = float(input('请输入数学成绩:'))
a3 = float(input('请输入英语成绩:'))
s = a1+a2+a3
avg = s / 3
print('姓名 语文 数学 英语 总分 平均')
print('%s %.1f %.1f %.1f %.2f %.2f'%(name, a1, a2, a3, s, avg ))
六、课后作业
编写一个程序,让用户在终端输入自己的姓名和身份证号,输出该用户的姓名和生日。
注:身份证号是一个18位的字符串,其中第7-10位是出生年份,11-12位是出生月份,13-14位是出生当天几号。注意,8月是08,5号是05,输出时不能带0。
示例: