字符串
借用维基百科上的解释,字符串(String),是由零个或多个字符组成的有限串行,一般记为s=a[1]a[2]...a[n]
。在Python中,字符串是一种对象类型,这种类型用str
表示,通常用单引号或者双引号包裹起来(都是半角符号)。
>>> "I love basketball"
'I love basketball'
>>> 'I love basketball'
'I love basketball'
从上面的结果可以知道,无论使用单引号还是双引号,结果都是一样的,都是字符串。
>>> type(100)
<class 'int'>
>>> type('100')
<class 'str'>
上面的代码通过type()
函数验证对象类型。前者是int
类型,或者是str
类型,区别只是后者被单引号包裹着。
来看看下面这个字符串应该怎么输出?
I'm Tom!
>>> 'I'm Tom!'
File "<stdin>", line 1
'I'm Tom!'
^
SyntaxError: invalid syntax
上面出现语法错误SyntaxError
,出现这样的错误是因为I
后面的单引号与前面的单引号凑成了一对,导致最后的单引号无法匹配所以出现语法错误。
解决方法一:使用双引号包裹单引号
>>> "I'm Tom!"
"I'm Tom!"
解决方法二:使用转义符
所谓转义,就是让某个符号不再表达式某个含义,而是表示另外一个含义。转义符的作用就是它能够转变符号的含义。在Python中,用符号\
作为转义符。
>>> 'I\'m Tom!'
"I'm Tom!"
字符串操作
字符串连接
我们使用 +
来连接两个字符串,我们直到在数字中使用 +
是将两个数字进行加运算,而用在两个字符串之间则会返回一个新的字符串。
>>> "Py" + "thon"
'Python'
看起来虽然简单,但如果是下面这样则会有点问题
>>> a = 123
>>> b = "Python"
>>> a + b
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'int' and 'str'
在之前的文章我们讲过,+
不能用于两个不同类型的对象。既然有问题,那么就需要解决问题,对于上面类似的问题,我们需要让这两个对象是同类型的,那很好办,让 a
变为字符串。
>>> a = 123
>>> b = "Python"
>>> b + str(a)
'Python123'
以上的 str()
函数可以将整数对象转换为字符串对象。还有另一种方法是使用 repr()
函数。
>>> a = 123
>>> b = "Python"
>>> b + repr(a)
'Python123'
通过以上的代码我们可以发现,实际上 repr()
函数实际上也是将 a
转化为字符串对象。而 repr()
与 str()
的区别在于:前者转化为供解释器读取的形式,返回指定值的字符串表示;后者将指定的值转换为字符串,也即是适于用户阅读的形式。
Python转义符
所谓转义,就是不采用符号本身的含义,而采用另一种含义。以下列出常用转义符:
转义字符 | 描述 |
---|---|
\ | (在行尾时)续行符,即一行未完,转下一行 |
\ | 反斜杠符号 |
\' | 单引号 |
\" | 双引号 |
\a | 响铃 |
\b | 退格(Backspace) |
\c | 转义 |
\000 | 空 |
\n | 换行 |
\v | 纵向制表符 |
\t | 横向制表符 |
\r | 回车 |
\f | 换页 |
\oyy | 八进制,yy代表的字符,例如:12代表换行 |
\xyy | 十六进制数,yy 代表的字符,,例如:0a代表换行 |
\other | 其他的数字以普通格式输出 |
>>> print("Hello,I\'m Tom, I like Python \nmy websit is \"www.tom.com\" ")
Hello,I'm Tom, I like Python
my websit is "www.tom.com"
print()
很显然解决了输出显示的问题,那输入呢?接下来我们就来介绍输入,这里需要用到input()
键盘输入
初次接触者可以现在交互模式下使用 help(input)
查看该内建函数的相关详情(按 q
退出)。下面直接代码演示。
>>> input("Enter your name:")
Enter your name:Tom
'Tom'
input()
返回的是一个字符串类型的对象,这样我们就可以用赋值语句将其返回值赋予一个变量方便在程序其他地方调用。
>>> name = input("Enter your name:")
Enter your name:Tom
>>> print("Hi,"+name,"Welcome to Ubantu!")
Hi,Tom Welcome to Ubantu!
我们也可以通过 type
确认input()
返回的对象类型。
>>> a = input("input something:")
input something:Tom
>>> b = input("input something:")
input something:24
>>> type(a)
<class 'str'>
>>> type(b)
<class 'str'>
由上可见无论输入什么,input()
否返回的是字符串类型对象,因此如果我们希望在程序中使用键盘输入的值且是数字的话需要将返回值转为整数型再使用。
原始字符串
何为原始字符串?就是指字符串里面每个字符都是原始含义,比如前面讲到的转义字符 \
,如果不被看作转义字符那么它就是原始含义。
>>> print("I like \nbasketball!")
I like
basketball!
>>> path = "D:\newbook"
>>> path
'D:\newbook'
>>> print(path)
D:
ewbook
在上面的两个例子中就出现了歧义,原本是想输出原始字符串,但刚好某个字符与\
组成转义符。我们可以用下面的方法来解决。
>>> path = "D:\\newbook"
>>> print(path)
D:\newbook
>>>
>>> path = r"D:\newbook"
>>> print(path)
D:\newbook
形如 r"D:\newbook"
,由 r
开头的字符串就是原始字符串,在里面放任何字符都会表示该字符的原始含义。
既然字符串可以由多个字符构成,那么是不是也可以分为多个字符?是的,这就是操作每个字符,需要使用到索引与切片。
索引和切片
一个字符串可以由多个字符组成,自然也可拆分为多个字符,那怎样才可以访问这些字符呢?可以使用索引来访问字符串中的某个字符。
>>> a = "Python"
>>> a[0]
'P'
>>> a[1]
'y'
注意 索引 是从0开始的,每个索引位对应每个字符,也就是索引是和其对应位置上的值是一一对应的。另外,Python比较特殊的一点是它支持负数索引。
>>> a[-1]
'n'
>>> a[-2]
'o'
>>> a[-6]
'P'
如果不太清楚负数索引是怎样访问的,可以用字符串长度减去负数绝对值,即可转换为整数的索引,结果是一致的。例如 6 - abs(-1) = 5
a[5] = 'n'
。
既然可以用索引找到对应的字符,那么是不是也可以通过字符找到其在字符串中对应的索引呢?答案肯定是可以的,我们可以使用index()
来查找
>>> a.index('P')
0
>>> a.index('y')
1
有时候我们可能需要的是字符串中的某部分子字符串,而不是单个,这时候又要怎么解决呢?我们可以使用 切片 的操作来获得字符串的字串也称之为字符串的切片。
>>> s = "I like Python very well"
>>> a = s[:6] # [:6]等价于[0:6]
>>> b = s[:] # 得到所有
>>> a
'I like'
>>> b
'I like Python very well'
>>> c = "abcdefghi"
>>> c[1:8:2] #从序号1到8(不包过8),步长为2
'bdfh'
在获取切片的时候,如果冒号前面不写数字,就表示从字符串的第一个开始(包括第一个);如果冒号后面的序号不写,就表示到字符串的最末一个字符结束(包括最后一个)。如果冒号后面有数字,且该数字小于等于字符串的长度,则表示从字符串的第一个字符开始到该数字的前一个字符。同样的,既然索引支持负数,那切片自然也支持负数。
>>> a = "I like Python and I study Python!"
>>> a[-3:-1]
'on'
>>> b = "abcdefghi"
>>> b[-8:-2:2]
'bdf'
注意,不管是使用正数切片还是负数切片,冒号左边的值必须比右边的值小(步长除外)。
字符串基本操作
字符串实际上也是一种序列,所有的序列都有以下基本的操作。
len()
:求序列长度+
:连接两个序列*
:重复序列元素in / not in
:判断元素是否存在于序列中max()
:返回序列中的最大值min()
:返回序列中的最小值
-
len()
求序列长度>>> str1 = "I like" >>> len(str1) 6
-
+
连接序列>>> str1 = "I like" >>> str2 = "Python" >>> str1 + str2 'I likePython'
-
*
重复序列元素>>> str2 = "Python" >>> str2 * 3 'PythonPythonPython'
-
in / not in
判断元素是否存在于序列中>>> str1 = "I like" >>> str2 = "Python" >>> "P" in str2 True >>> "I" in str1 True >>> str3 = str1 + str2 >>> str1 in str3 True >>> str2 not in str3 False
in / not in
用来判断某个字符串是否在另一个字符串内,或者说判断某个字符串内是否包含另外一个字符串(此字符串也被称为子字符串)。如果包含就返回True
,否则返回False
。 -
最值比较
>>> max(str1) 'l' >>> max(str2) 'y'
字符串中的字符也分大小的。前面我们说过,在英文字典中,所有字母都有排序的,实际上这些字母是通过编码成对应的数字之后再进行排序的。而
max()
和min()
就是根据这个顺序来获取最值的。我们可以使用下面这个函数来查看字符对应的数字编码。>>> ord('y') 121 >>> ord('l') 108
同样道理,也可以反过来使用
chr()
函数由数字编码转化为字符。>> chr(110) 'n' >>> chr(120) 'x'
有兴趣的可以去搜索一下
ASCII
码表,上面记录基本所有字符对应的数字编码。
字符串格式化输出
格式化字符串,是 C、C++
等程序设计语言 printf
类函数中用于指定输出参数的格式与相对位置的字符串参数。其中的转换说明用于把随后对应的0个或多个函数参数转换为相应的格式输出;格式化字符串中转换说明以外的其他字符原样输出。
以上是来自《维基百科》的定义,在这个定义中,是用C语言作为例子。在Python中,也有同样的操作——print()
函数。如果将维基百科的定义再通俗化,所谓字符串格式化,就是要先定制一个模板,在这个模板中某个或者某几个地方留出空位来,然后再那些空位填上字符串,并且在显示结果中,字符串要符合空位置所设定的约束条件。下面是Python常见的字符串格式化符号:
符号 | 描述 |
---|---|
%c | 格式化字符及其ASCII码 |
%s | 格式化字符串 |
%d | 格式化整数 |
%u | 格式化无符号整型 |
%o | 格式化无符号八进制数 |
%x | 格式化无符号十六进制数 |
%X | 格式化无符号十六进制数(大写) |
%f | 格式化浮点数字,可指定小数点后的精度 |
%e | 用科学计数法格式化浮点数 |
%E | 作用同%e,用科学计数法格式化浮点数 |
%g | %f 和 %e 的简写 |
%G | %f 和 %E 的简写 |
%p | 用十六进制数格式化变量的地址 |
那些空位需要用一个符号来表示,这个符号通常被叫作占位符(仅仅是占据着那个位置,并不输出内容)。
>>> "I like %s"
'I like %s'
比如像上面的示例字符串中有一个符号 %s
它就是占位符,这个占位符可以被其他字符串代替,如:
>>> "I like %s" % "Python"
'I like Python'
不过现在比较不提倡这种使用方法,因为Python2.6开始引用format()
由于其方便且功能强大,因此现在比较提倡使用 format()
来进行字符串的格式化。
>>> "I use {0} and {1}".format("Python","shell")
'I use Python and shell'
在上面示例的字符串中,用 {0}
和 {1}
占据了两个位置,它们就是占位符,且它们是按顺序对应的,即第一个参数传入的 Python
对应着 {0}
,第二个参数传入的 shell
对应着 {1}
。
>>> "I use {0:10} and {1:>15}".format("Python","shell")
'I use Python and shell'
以上是有格式的方式。{0:10}
表示第一个位置,有10个字符那么长,并且放在这个位置的字符是左对齐;{1:>15}
表示第二个位置,有15个字符那么长,并且放在这个位置的字符是右对齐。
>>> "I use {0:^10} and {1:^15}".format("Python","shell")
'I use Python and shell '
以上是居中对齐的情况。
>>> "I use {0:.2} and {1:^10.4}".format("Python","shell")
'I use Py and shel '
{0:.2}
这里的 0
说明是第一个位置,对应传入的第一个字符串。.2
表示对于传入的字符串,截取前两个字符,并放到第一个位置。需要注意的是,在冒号 :
后面的句点 .
前面,没有任何数字,意思是该位置的长度自动适应即将放到该位置的字符串。
{1:^10.4}
这里 1
说明是第二个位置,对应传入的第二个字符串。^
表示放到该位置的字符串要居中。10.4
表示该位置的长度是10个字符那么长,但即将放入该位置的字符串应该仅仅有4个字符那么长,也就是要从传入的字符串 shell
中截取前四个字符,即为 shel
。
format()
中除了能够传入字符串外,还可以传入数字(包括整数和浮点数)。
>>> "I am {0:d} years old and height is {1:f}cm".format(18,180.12345)
'I am 18 years old and height is 180.123450cm'
{0:d}
表示在第一个位置放一个整数;{1:f}
表示在第二个位置放一个浮点数,那么浮点数的小数位数是默认的。下面再演示一些格式化:
>>> "I am {0:4d} years old and height is {1:6.2f}cm".format(18,180.12345)
'I am 18 years old and height is 180.12cm'
{0:4d}
表示第一个位置的长度是4个字符,并且默认状态下,填充到该位置上的整数是右对齐。{1:6.2f}
表示第二个位置的长度是6个字符,并且填充到该位置的浮点数要保留两位小数,默认也是右对齐。
>>> "I am {0:04d} years old and height is {1:06.2f}cm".format(18,180.12345)
'I am 0018 years old and height is 180.12cm'
{0:04d}
和 {1:06.2f}
与上述不同的地方在于,在声明位置长度的数字前面多了0,其含义是在数字前面,如果位数不足,则补0。
>>> "I like {language} and {name}".format(language="Python",name="You")
'I like Python and You'
format()
还有很多做字符串格式化输出的方式,这里只简单介绍一些基本常见的。
常用的字符串方法
-
判断是否全是字母
isalpha()
>>> "Python".isalpha() True >>> "Python3.8".isalpha() False
-
根据分隔符分割字符串
split()
>>> s = "Python is a language" >>> s.split(" ") ['Python', 'is', 'a', 'language'] >>> s = "Python,Java,C,C++" >>> s.split(",") ['Python', 'Java', 'C', 'C++']
注意该函数返回的是一个列表。
-
去掉字符串两头的空格
S.strip()
:去掉字符串的左右空格S.lstrip()
:去掉字符串的左边空格S.rstrip()
:去掉字符串的右边空格
>>> s = " hi " >>> s.strip() 'hi' >>> s ' hi ' >>> s.lstrip() 'hi ' >>> s.rstrip() ' hi'
由以上可知,调用该函数原来的值并没有改变,而是返回一个新的结果而已。
-
字符大小写的转换
S.upper()
:S 中的字母转化为大写S.lower()
:S 中的字母转化为小写S.capitalize()
:将首字母转化为大写S.isupper()
:判断 S 中的字母是否全是大写S.islower()
:判断 S 中的字母是否全是小写S.istitle()
:判断 S 是否是标题模式,即字符串中所有单词拼写首字母为大写,且其他字母为小写。
>>> a = "Python" >>> a.upper() 'PYTHON' >>> b = "NBA.COM" >>> b.lower() 'nba.com' >>> c = "my name is mr.zhang" >>> c.capitalize() 'My name is mr.zhang' # 注意以上的三个方法都是生成一个新的字符串,没有修改原字符串
>>> a = "abcdefg" >>> a.islower() True >>> a.isupper() False >>> b = "PYTHON" >>> b.isupper() True >>> b.islower() False >>> c = "Python My Favoriate" >>> c.istitle() True
-
用
join()
拼接字符串前面说过在打印字符串的时候可以用
+
来连接字符串,由于+
不是在所有情况下都适用,比如要将列表中的每一项都串联起来且用某个符号作为连接符,这种情况下用+
就会很麻烦。下面介绍一种比较好用的方法join()
。>>> a = "www.github.com" >>> b = a.split(".") >>> b ['www', 'github', 'com'] >>> ".".join(b) 'www.github.com' >>> "-".join(b) 'www-github-com'
字符编码
在 Python3 中所有的字符串都是 Unicode
字符串。在前面我们介绍过实现字符及编码相互转换的函数
>>> ord("A")
65
>>> chr(65)
'A'
而对于汉字则是这样的:
>>> ord("你")
20320
>>> chr(20320)
'你'
因为 Python3 支持的是 Unicode
,所以每个汉字都对应一个编码数字。除此之外,字符串还有一个 encode
方法,该方法能够将 Unicode
编码的字符串转化为其他编码,默认是 UTF-8
。我们在编程中通常要声明 coding:utf-8
以免遇到乱码等问题。
好了,字符串专辑就差不多到这了。但 Python 知识还需继续。我们下期见。