目 录
字符串
创建字符串对象
用一对单引号或者双引号创建字符串
将字符串的内容(即若干个字符)用一对单引号或者双引号括起来,就创建了一个字符串对象。例如:
>>> 'Hello' 'Hello' >>> "Hello" 'Hello' >>> "Hello, Python!" 'Hello, Python!'
这两种符号创建字符串对象的效果是完全相同的。Python允许用这两种等价的方式创建字符串对象的一个重要好处就是当字符串本身如果包含引号时,就可以选择用另一种引号来创建。例如:
>>> '小刘看到老师时热情地说:"王老师,早上好!"' '小刘看到老师时热情地说:"王老师,早上好!"'
需要说明的是,用print()函数输出字符串的效果跟上面交互式环境下回显的效果有一些区别的。交互式环境下回显的所有字符串都有一对单引号括起来,而print()函数的输出则只有字符串内容本身。例如:
>>> print('小刘看到老师时热情地说:"王老师,早上好!"') 小刘看到老师时热情地说:"王老师,早上好!"
使用三引号创建字符串对象
Python也允许使用一对三个单引号(''')或者三个双引号(""")来创建字符串对象,使用的方法与效果和前面的单引号和双引号是相同的。不同之处在于三引号能够创建多行字符串,也就是字符串中存在回车换行情况,例如一首诗歌。
>>> poem = '''轻轻的我走了, ···正如我轻轻地来, ···我轻轻地招手, ···作别西天的云彩。''' >>> print( poem ) 轻轻的我走了, 正如我轻轻地来, 我轻轻地招手, 作别西天的云彩。
因此,通常在输入比较长的且是多行的字符串时,就用三引号。例如在程序中的注释或者对函数、类等的说明性文字,就需要用三引号。
使用str()函数创建字符串
Python提供的内置函数str(),能够把其它类型的对象转换为字符串型对象。例如:
>>> str(15) '15' >>> str(1.25) '1.25' >>> str([1,2,3]) '[1, 2, 3]' >>> str(True) 'True'
使用转义字符
当字符串中包含难以用键盘输入的符号时,例如回车换行、制表符、单引号双引号等,这时就可用转义字符(escape character)来协助输入。转义字符就是反斜杠“\”后面再紧跟着一个特定字符。Python会将它们作为一个整体解释为特殊的含义。
例如当某个的字符串需要在多行来显示(例如诗歌或者文章中的新一段),那么在输入过程中就需要点击回车键。但是正常情况下Python解释器会将输入回车解释为字符串输入结束,因此就会出错。这时就可通过转义字符“\n”来表示此处有一个回车,从而让输入时看起来是单行的字符串,但是在输出显示时会表现为多行的效果。这个过程中隐含着Python解释器中的一个约定:即当字符串中出现符合“\”时,那么解释器就根据其后紧跟的一个字符的不同来对其作不同的解释。
例如:
>>> a = "轻轻地我走了,\n正如我轻轻地来。" >>> a '轻轻地我走了,\n正如我轻轻地来。' >>> print(a) 轻轻地我走了, 正如我轻轻地来。
再次说明一下,在交互式环境下直接显示字符串和通过print()函数来显示字符串通常有些区别。例如上例中在交互式环境中显示字符串a时,会统一用一对单引号括起来,并且里面的转义字符“\n”被直接显示,而未被解释为换行。而在print()函数中显示该字符串时,就是我们希望看到的样子。
很多编程语言在实现输入和显示多行文本时都是采用转移字符“\n”来表示回车换行的。不过,Python有更简单的方式,就是前面介绍的使用三引号。但是“\n”也不是完全可以被三引号所代替。例如在程序中,已经有了两个字符串变量s1和s2,我们希望将这两个字符串连接起来形成一个字符串,这可以通过“+”运算符来实现(下面紧接着会讲这个)。当如果还要求这两个字符串必须显示在两行里,例如诗歌,那么就要用到“\n”了。代码如下:
>>> s1 = "轻轻地我走了," >>> s2 = "正如我轻轻地来。" >>> s = s1 + '\n' + s2 >>> print(s) 轻轻地我走了, 正如我轻轻地来。
另一个重要的转义字符就是用“\t”来表示制表符,即Tab键,这在需要格式化输出的情况下非常有用。例如,某超市要打印输出顾客的购买清单,每行打印一个商品的名称和单价,如果顾客购买了多种商品,那么就需要打印多行。大家应该都能设计出每行信息的显示格式:即先显示商品名称,然后显示商品单价,并且两者间用空格分开。但是,当商品的名称的长短不同时,如果用一个或者两个空格分开,效果看起来就比较混乱。为了感受到这种混乱,下面在编辑环境(而不是交互式环境)中来看看效果。
首先,商品名称和单价之间用一个空格隔开:
>>> print('白菜, 1.20') >>> print('西兰花, 3.50') >>> print('蒜, 2.99') >>> print('紫甘蓝, 3.99')
显示的效果是:
白菜, 1.20
西兰花, 3.50
蒜, 2.99
紫甘蓝, 3.99
而如果两者间加入转义字符“\t”(代码中实际上加入了两个“\t”):
>>> print('白菜, \t\t1.20') >>> print('西兰花, \t\t3.50') >>> print('蒜, \t\t2.99') >>> print('紫甘蓝, \t\t3.99')
看到的效果就明显整齐了:
白菜, 1.20
西兰花, 3.50
蒜, 2.99
紫甘蓝, 3.99
那么,如果字符串中本身就包含反斜杠“\”时,如何输入呢?Python规定同时输入两个反斜杠“\\”时,Python解释器遇到第一个反斜杠时视作转义符,从而将第二个反斜杠解释为反斜杠本身,不会再视作转义符了。
同样地,如果字符串本身就包含单引号(')或者双引号("),如果不加转义符,Python会将其解释为字符串的开始或者结束,引发错误。这时输入“\'”或者“\"”,Python就将其解释为引号本身,而不会当作字符串开始或结束的标志了。不过,由于Python语言允许用一对单引号或者双引号来表示字符串,因此上述这种情况可以不用转义符来解决。例如字符串中本身如果包含着一对双引号,那么就用一对单引号来创建此字符串,当一对单引号中包含双引号时,Python解释器会自动将内部的双引号视作符号本身,而不会将之解释为字符串的开始或者结束了。
索引与切片
索引
想要获得字符串中的某个字符,可以通过在字符串对象后面紧跟着一对方括号“[]”来实现,方括号中指定要获得的字符在整个字符串中的位置偏移量,这称作字符串索引。位置偏移量也称为索引值或者下标,它是从0开始的,如下图所示:
索引的语法格式为:S[n],其中S为一字符串对象,n为字符的位置偏移量。字符串对象既可以是字符串的字面值形式,也可以是变量形式。例如:
>>> "abc"[1] 'b' >>> print("abc"[1]) b >>> s = "abc" >>> s[1] 'b' >>> print(s[1]) b
首先要强调的是,字符串中字符的偏移值(即索引值)是从0开始的。
如果懂得C或者Java编程语言的话,就会发现它与访问一个数组的元素的做法相同。其实大多数语言中访问数组元素的做法也都类似,即通过一对方括号中指定索引值来访问其中的元素。在Python语言中,字符串类型连同下面将要学习的列表(list)类型、元组(tuple)类型,都属于一个更大的类型:即序列类型(sequence)。它们在内存中有相同的存储方式:即按照特定顺序依次排列对象中包含的数据。因此它们也都支持通过方括号和偏移值来访问其中的元素数据。
索引值也可以是负数,这时表示从字符串的右边往左边数,即通常所说的“倒着数”。但是要注意的是,如果顺着数,索引值是从0开始的,如果倒着数,索引值是从1开始的,即倒数第一个字符的索引值为-1。如下图所示:
元素1 |
元素2 |
元素3 |
元素n-1 |
元素n |
||
正向索引值 |
0 |
1 |
2 |
n-2 |
n-1 |
|
反向索引值 |
-n |
-(n-1) |
-(n-2) |
-2 |
-1 |
例如
>>> s = "abc" >>> s[-1] 'c' >>> s[-2] 'b'
切片
切片与索引的类似之处在于都是通过偏移值来获得字符串中的字符。不同之处在于索引是通过一个偏移值来获得字符串中的一个指定字符,而切片是通过偏移的起始值和终止值来获得字符串的一个字串(即多个字符)。切片就如同用刀把一个字符串“切”下来一片。
假设s表示一个字符串对象,则s[start:end]表示s中从偏移值start开始到end结束之间的所有字符,即s的一个字串。但是特别注意:字串中包含偏移值为start的字符,而不包含偏移值为end的字符。简单地说,就是包含起始偏移的字符,不包含结束偏移的字符。例如:
>>> s = 'abcdefg' >>> s[1:5] 'bcde' >>> s[0:7] #获得字符串中所有字符 'abcdefg'
所以,如果要获得字符串中所有字符,就须将起始偏移设置为0,将结束偏移设置为字符串的长度值。
切片操作也允许有省略的写法:如果不指定起始偏移值,则默认为0,即从字符串的第一个字符开始;如果不指定结束偏移值,则默认为字符串长度,即到字符串的最后一个字符。如果起始偏移和结束偏移都省略,这时方括号内只有一个冒号了,那么就表示从字符串的第一个字符到最后一个字符。例如:
>>> s = 'abcdefg' >>> s[:5] 'abcde' >>> s[1:] 'bcdefg' >>> s[:] 'abcdefg'
切片操作中也允许使用负数,即倒着数。例如对于一个很长的字符串s,希望得到其第一个字符到倒数第三个字符,就可以用s[0:-2]来实现。或者当要得到s中倒数第6个字符到倒数第3个字符间的所有字符,可用s[-6:-2]。这里有一个细节在前面已经讲过了,就是切片的结果中不包含结束偏移处的字符。所以当你需要包含倒数第三个字符时,那么结束偏移值一定要指定到倒数第二个字符的倒数偏移值。代码如下:
>>> s = 'abcdefghijklmnopqrstuvwxyz' >>> s[0:-2] 'abcdefghijklmnopqrstuvwx' >>> s[-6:-2] 'uvwx'
正常来说,切片中的起始偏移所对应的位置应该在结束偏移所对应的位置的左面,这符合我们从左往右数的习惯。但是如果将切片中的起始偏移设置在了结束偏移的右面(很多时候这是粗心造成的一个错误),但是Python不会报错的,它会返回一个空字符串。例如:
>>> s = 'abcdefghijklmnopqrstuvwxyz' >>> s[6:2] '' >>> s[-3:-7] '' >>> s[26:-3] ''
扩展的切片操作
前面学习的切片操作通过指定起始偏移和结束偏移来获得两者之间包含的所以字符。Python还允许再指定一个步长值,表示在起始偏移和结束偏移之间每隔多少个字符(即步长)来切下一片。其语法格式为:s[start:end:step],其中s表示一个字符串对象,start和end含义同前面相同。此处增加的一个参数end为一整数,表示“每向前走end个字符即切下来一个字符”。通过下面例子来理解其含义:
>>> s = 'abcdefghijklmnopqrstuvwxyz' >>> s[1:10:2] 'bdfhj' >>> s[1:11:2] 'bdfhj'
前面在没有指定步长值的时候已经知道了切片的起始偏移所对应的位置必须在结束偏移所对应的位置的左面。现在指定了步长值的时候这种约束就有些变化了:切片的起始偏移所对应的位置在结束偏移所对应的位置的右面,并且步长值为负数时,表示将字符串对象从右向左方向进行反向切片。示例如下:
>>> s = 'abcdefghijklmnopqrstuvwxyz' >>> s[26:0:-2] 'zxvtrpnljhfdb'
s[26:0:-2]表示从字符串s中从偏移量为26的位置开始向左一直到偏移量为0的字符处,每两个字符就切下一个字符。
因此,将字符串s进行反转的方法就是s[26:-27:-1],或者更简洁的写法就是s[::-1]。如下:
>>> s = 'abcdefghijklmnopqrstuvwxyz' >>> s[26:-27:-1] 'zyxwvutsrqponmlkjihgfedcba' >>> s[::-1] 'zyxwvutsrqponmlkjihgfedcba'
使用+和*运算符
在前面学习运算符时已经了解了+和*这两个运算符,它们能够对数值型数据进行加法和乘法运算。这两个运算符同样也能应用与字符串,但含义有所不同。
使用+运算符拼接字符串
运算符+能够将两个字符串拼接起来。假设s1和s2分别表示两个字符串对象,它们既可以是字面值字符串,也可以是字符串变量,则表达式“s1 + s2”的结果是连个字符串s1和s2的拼接。例如:
>>> 'abc' + 'def' 'abcdef' >>> s1 = 'abc' >>> s2 = 'def' >>> s1 + s2 'abcdef'
运算符+只是简单地将两个运算符前后拼接起来,不会给它们之间添加空格。因此,如果希望得到一句话这一的结果,例如“Good morning!”,其中两个单词之间存在一个空格,有两个实现方式:要么在定义两个单词的时候就将空格包含于其中,要么在进行+运算时单独加入一个空格。如下:
>>> 'Good ' + 'morning!' 'Good morning!' >>> 'Good' + ' ' + 'morning!' 'Good morning!'
print()函数允许将多个字符串对象作为参数,其打印结果中会自动在各个字符串参数间加上一个空格。如下:
>>> s1 = 'Good ' >>> s2 = 'morning!' >>> print(s1, s2) Good morning!
使用*运算符重复字符串
运算符*能够将一个字符串以拼接的形式重复多次,其格式为:s * n,其中s表示一个字符串对象,n为一个整型数值,表示要重复的次数。例如:
>>> 'Hello' * 2 'HelloHello' >>> 'Hello' * 3 'HelloHelloHello' >>> 'Hello' * 0 '' >>> 'Hello' * -1 ''
当n为0或者负整数的时候,结果就是一个空字符串。
使用in运算符
字符串属于一种序列类型数据,因此,与成员运算符 in 相结合时,能够判断一个字符串中是否存在某个子串。假如s1和s为两个字符串,那么“s1 in s”为一个表达式,当字符串s1是s的一个子串时,该表达式的值为True,否则,表达式为False。例如:
>>> 'a' in 'abcde' True >>> 'cd' in 'abcde' True >>> 'g' in 'abcde' False
因此,表达式“s1 in s”可以作为if语句中的条件判断表达式,构成条件判断的复合语句。例如判断一个文本中是否包含某个单词:
>>> txt = 'Wang is a student.' >>> if 'Wang' in txt: ··· print('Yes') ···else: ··· print('No') ··· Yes
此外,由于字符串也属于序列型对象,因此可以在“for - in”遍历循环中扮演可迭代对象的角色,控制循环过程。例如下面例子中遍历并打印一个字符串中的每个字符:
>>> for char in 'abcde': ··· print(char) ··· a b c d e #此处为竖向输出,为节约篇幅改为显示在同一行。
使用字符串方法
Python语言提供的部分内置函数能够应用于字符串对象,例如len()函数能够获得字符串的长度,id()函数能够获取字符串在内存中的地址。除此之外,Python还专门为字符串对象提供了大量的方法,能够实现更复杂的文本处理任务。
在这里使用了字符串“方法”这个称谓,而没有用字符串“函数”这个称谓,这里涉及到了面向对象设计思想的知识。方法和函数在表面样子来看是一样的,都是一个名称后面跟着参数列表,能够完成特定任务的代码块。其区别主要在于设计思想上。可以将“方法”理解是“函数”在面向对象中的一个别称,它特定于某一类对象。因此,方法的使用语法格式通常是:obj.method_name(params),其中obj是一个对象,method_name为方法名,它通过句点“.”表示该方法是obj对象特有的一个属性。方法名之后的一对圆括号内是方法的参数列表。
下面选择一些较常用的方法来介绍。
replace()方法修改字符串
replace()方法能够用一个新字符串来替换原字符串中的某个旧字符。其语法格式为:replace(old, new[, count]),其中old为要被替换的旧字符串,new为将要替换成的新字符串,count是一个可选参数,指定最多有count个旧字符串被替换。例如:
>>> s1 = "I like bananas" >>> s2 = s1.replace('bananas','apples') >>> print(s2) I like apples
下面我们再来学习count参数的作用:
>>> s1 = 'Ke Ke is a boy, his mother says "Ke Ke get up!"' >>> s2 = s1.replace('Ke','Le') >>> s3 = s1.replace('Ke','Le',2) >>> print(s1) Ke Ke is a boy, his mother says "Ke Ke get up!" >>> print(s2) Le Le is a boy, his mother says "Le Le get up!" >>> print(s3) Le Le is a boy, his mother says "Ke Ke get up!"
在这里应注意一个细节知识,Python语言中,字符串对象属于不可变对象,也就是说一个字符串对象的值是不可改变的。因此,通过replace()方法修改一个字符串对象的内容后,并不是在原有字符串基础上进行“修改”的,而是直接创建了一个新的字符串,新的字符串的内容就是修改后的内容,原先的字符串并没有被“修改”,从下面代码可以看出这一点:
>>> s1 = 'abcde' >>> s2 = s1.replace('de','ww') >>> print(s1) abcde >>> print(s2) abcww
因此,对字符串对象进行操作时应慎重,尤其是比较长的字符串(例如一篇文章),即使只修改了其中一个字符,背后实际上都重新创建了一个新的字符串对象,这是非常耗费内存和时间的。
find()和index()搜索字符串
如果要在一个字符串中搜索某个字符(串)出现的位置,可以使用find()和index()这两个方法。这两个方法的语法格式是相同的:
find(sub[, start[, end]])
index(sub[, start[, end]])
其中参数sub为要搜索的某个字符(串),start和end为两个可选参数,分别指定搜索范围的起始和结束位置。两个方法都返回sub在整个字符串对象中第一次出现的位置偏移值。
例如:
>>> s = "Hello, welcome to Python" >>> x = s.find('to') >>> y = s.index('to') >>> print(x) 15 >>> print(y) 15
如果要搜索的子串在原字符串中出现多次,两个方法都返回第一次出现的位置。例如:
>>> s = "Hello, welcome to Python" >>> x = s.find('e') >>> y = s.index('e') >>> print(x) 1 >>> print(y) 1
如果要获得字串最后出现的位置,Python还提供了另外两个相似的方法来实现:rfind()和rindex(),它们的语法格式为:
rfind(sub[, start[, end]])
rindex(sub[, start[, end]])
其中的参数的含义分别与find()和index()的相同。它们的区别是find()和index()方法返回所搜索的子串在原字符串中第一次出现的位置,而rfind()和rindex()则返回最后一次出现的位置。例如:
>>> s = "Hello, welcome to Python" >>> x = s.rfind('e') >>> y = s.rindex('e') >>> print(x) 13 >>> print(y) 13
这四个函数都可以在指定的位置范围进行搜索:
>>> s = "Hello, welcome to Python" >>> x = s.find('e',6,10) >>> y = s.index('e',6,10) >>> print(x) 8 >>> print(y) 8
如果想知道某个子串总共出现的次数,可以使用方法count()来实现,例如:
>>> s = "Hello, welcome to Python" >>> x = s.count('e') >>> print(x) 3
到此为止,可以看出find()和index()这两个方法的功能用法都是相同的。事实上,两个方法的唯一区别在于如果要搜索的子串不存在时,find()方法就返回-1,而index()则会报错(rfind()和rindex()的区别也是如此)。
>>> s = "Hello, welcome to Python" >>> x = s.find('mm') >>> y = s.index('mm') Traceback (most recent call last): File "<pyshell#33>", line 1, in <module> y = s.index('mm') ValueError: substring not found >>> print(x) -1
split()方法拆分字符串
split()方法能够按照指定的分割标识将一个长的字符串拆分为多个短的字串,该方法的语法格式为:
split(sep=None, maxsplit=-1)
其中参数sep指定分割的标识,maxsplit为分割的最大数目,默认值为-1表示不设最大的分割上限。该方法返回一个列表对象,其中包含着全部拆分而得的子串。例如:
>>> s = "Hello, I am a student, I come from China." >>> s1 = s.split(',') >>> print(s1) ['Hello', ' I am a student', ' I come from China.']
该方法会从字符串左端开始搜索,如果遇到了指定的分隔符,就以此为分界线,将字符串分为前后两个子串,但分隔符被丢弃掉。然后接着在后面的子串中继续搜索,如果再次遇到分隔符,就将后面这个子串分割为前后两部分。这时整个字符串已经被分割为三个子串了。这个过程会重复地进行下去,直至字符串末尾处。如果指定分割的最大次数的话,当达到最大次数时,就不会再继续搜索和分割了。例如上面这个例子,如果指定分割次数为1的话,那么结果就会将字符串s分割为两个子串,如下:
>>> s = "Hello, I am a student, I come from China." >>> s1 = s.split(',',1) >>> print(s1) ['Hello', ' I am a student, I come from China.']
如果给split()方法不传递参数,也就是不指定分割符的话,那么就会以空白字符作为分割符,空白字符包括:空格、换行符“\n”、制表符“\t”。例如:
>>> s1 = "I am a student." >>> s2 = "I\tam a\nstudent." >>> print(s1.split()) ['I', 'am', 'a', 'student.'] >>> print(s2.split()) ['I', 'am', 'a', 'student.']
Python为字符串对象提供的方法非常多,我们不会逐一地全部介绍。有些方法的使用也比较简单,例如strip()方法能够剔除掉字符串前后的空格或者指定的字符,islower()和isupper()能够判断字符串中的字符是否都为小写的或者大写的。isdigit()方法能够判断一个字符串中的字符是否都是数字,这在将一个字符串对象转换为数值型对象时非常有用。通过下面Python官网链接可以查看Python所有字符串方法:
https://www.w3schools.com/python/python_ref_string.asp
https://docs.python.org/3/library/stdtypes.html#str
https://docs.python.org/3/library/stdtypes.html#text-sequence-type-str
https://docs.python.org/3/library/stdtypes.html#string-methods
标签:字符,Python,s1,print,偏移,字符串,第四章 From: https://www.cnblogs.com/mixiaoya/p/18019640