实际上,字符串是即将学习的从属于稍大一些的对象类别——序列的第一个代表。要格外留意这里介绍的序列操作,因为它在今后要学习的其他序列类型(例如列表和元祖)中也同样适用。
==========================================================================================
单双引号字符串是一样的
>>> 'shrubbery',"shrubbery"
('shrubbery', 'shrubbery')
可以在一个双引号字符所包含的字符串中嵌入一个单引号字符,反之亦然
>>> 'knight"s',"knight's"
('knight"s', "knight's")
此外,Python自动在任意的表达式中合并相邻的字符串常量,尽管可以简单地在它们之间增加+操作符来明确表示这是一个合并操作(把这种形式放到圆括号中,就可以允许它跨越多行)
>>> title = "Meaning "'of'" Life"
>>> title
'Meaning of Life'
注意:在这些字符串之间增加逗号会创建一个元组,而不是一个字符串。并且Python倾向于打印所有这些形式的字符串为单引号,除非字符串内有了单引号了。也可以通过反斜杠转义字符去嵌入引号:
>>> 'knight\'s',"knight\"s"
("knight's", 'knight"s')
=======================================================
===================================
用转义序列代表特殊字节
反斜杠用来引入特殊的字节编码,是转义序列
>>> s = 'a\nb\tc'
>>> s
'a\nb\tc'
>>> print(s)
a
b c
>>> len(s)
5
字符串反斜杠字符
转义 | 意义 |
\newline | 忽视(连续) |
\\ | 反斜杠(保留\) |
\' | 单引号(保留') |
\" | 双引号(保留") |
\a | 响铃 |
\b | 倒退 |
\f | 换页 |
\n | 换行 |
\r | 返回 |
\t | 水平制表符 |
\v | 垂直制表符 |
\N{id} | Unicode数据库ID |
\uhhhh | Unicode16位的十六进制值 |
\uhhhhhhhh | Unicode32位的十六进制值 |
\xhh | 十六进制值 |
\ooo | 八进制值 |
\0 | Null(不是字符串结尾) |
\other | 不转义(保留) |
python 以十六进制显示非打印的字符,不管是如何指定它们的:
>>> s = '\001\002\x03'
>>> s
'\x01\x02\x03'
如果Python没有作为一个合法的转义编码识别出在'\'后的字符,它就直接在最终的字符串中保留反斜杠
>>> x = 'C:\py\code'
>>> x
'C:\\py\\code'
>>> print(x)
C:\py\code
=======================================================
===================================
raw字符串抑制转义
myfile = open('C:\new\text.dat','w')
这并不会打开一个在C:\new目录下的名为text.dat的文件,问题是这里有‘\n’,它会识别为一个换行字符,并且'\t'会被一个制表符所替代
使用raw字符串:如果字符R或r出现在字符串的第一个引号前面,它就会关闭转义机制。这个结果就是Python会将反斜杠作为常量来保持,就像输入的那样,因此为了避免这种文件名的错误,记得增加字母r:
myfile = open(r'C:\new\text.dat','w')
还有一种方法:因为两个反斜杠是一个反斜杠的转义序列,能过通过简单地写两个反斜杠线去保留反斜杠:
myfile = open('C:\\new\\text.dat','w')
=======================================================
===================================
三重引号编写多行字符串块
字符串块:以三重引号开始(单引号和双引号都可以),并紧跟任意行数的文本,并且以开始时同样的三重引号结尾。嵌入在这个字符串文本中的单引号和双引号也会,但不是必须转义——直到Python看到和这个常量开始时同样的三重引号,这个字符串才会结束。例如:
>>> s = '''I have a dream
that
some day
there are '''
>>> s
'I have a dream\nthat\nsome day\nthere are '
三重引号字符串在程序中需要输入多行文本的任何时候都是很有用的。例如,嵌入多行错误信息或在源文件中编写HTML或XML代码。我们能够直接在脚本中嵌入这样的文本块,而不需要求助于外部的文本文件。
实际中,可以利用这个三重引号来注释多行代码,不用一行行地添加‘#’号(黑客风格)
==========================================================================================
字符串基本操作
>>> len('abc')
3
>>> 'abc'+'def'
'abcdef'
>>> 'Hi!'*4
'Hi!Hi!Hi!Hi!'
重复最初看起来有些费解,然而有时候却十分顺手。例如,为了打印包含80个横线的一行,你可以一个一个数到80,或者让Python帮你数!可以使用for语句在一个字符串中进行循环迭代,并使用in表达式操作符对字符和子字符串进行成员关系的测试,这实际上是一种搜索。对于子字符串,in很像是str.find()方法,但是,它返回的是一个布尔结果而不是子字符串的位置:
>>> for c in myjob:print(c,end=' ')
h a c k e r
>>> 'k' in myjob
True
>>> 'z' in myjob
False
>>> 'spam' in 'abcspamdef'
True
=======================================================
===================================
索引和分片
在Python中,字符串中的字符是通过索引(通过在字符串之后的方括号中提供所需要的元素的数字偏移量)提取的。
就像C语言一样,Python的偏移量是从0开始的,并比字符串的长度小1.
与C语言不同,Python还支持类似在字符串中使用负偏移这样的方法从序列中获取元素。
从技术上讲,一个负偏移与这个字符串的长度相加后得到这个字符串的正的偏移值。能够将负偏移看做是从结束处反向计数。
>>> s = 'spam'
>>> s[0],s[-2]
('s', 'a')
>>> s[1:3],s[1:],s[:-1]
('pa', 'pam', 'spa')
概括如下:
【1】索引(s[i])获取特定偏移的元素:
第一个元素的偏移为0
负偏移索引意味着从最后或右边反向进行计数
s[0]获取了第一个元素
s[-2]获取了倒数第二个元素(就像s[len(s)-2]一样)
【2】分片(s[i:j])提取对应的部分作为一个序列:
上边界并不包含在内
分片的边界默认为0和序列的长度,如果没有给出的话,举例如下:
s[1:3]获取了从偏移为1的元素,直到但不包括偏移为3的元素
s[1:]获取了从偏移为1直到末尾(偏移为序列长度)之间的元素
s[:3]获取了从偏移为0直到但是不包括偏移为3之间的元素
s[:-1]获取了从偏移为0直到但是不包括最后一个元素之间的元素
s[:]获取了从偏移0到末尾之间的元素,这有效地实现了顶层s拷贝
==========================================================================================
扩展分片:第三个限制值
在Python2.3中,分片表达式增加了一个可选的第三个索引,用作步进(有时称为是stride)。完整的分片形式现在变成了X[I:J:K]。这表示“索引X对象中的元素,从偏移为I直到偏移为J-1,每隔K元素索引一次”。第三个限制K,默认为1,这也就是通常在一个切片从左至右提取每一个元素的原因。如果定义了一个明确的值,那么能够使用第三个限制去跳过某些元素或反向排列他们的顺序。
>>> x = 'abcdefghijklmn'
>>> x[::2]
'acegikm'
如同往常,第一个和第二个限制值默认为0以及序列的长度,所以,x[::2]会取出序列从头到尾、每隔一个元素的元素。
也可以使用负数作为步进。例如,分片表达式“hello”[::-1]返回一个新的字符串“olleh”,步进-1表示分片将会从右至左进行而不是通常的从左至右。因此,实际效果就是将序列进行反转:
>>> S = 'hello'
>>> S[::-1]
'olleh'
通过一个负数步进,两个边界的意义实际上进行了反转。也就是说,分片S[5:1:-1]以反转的顺序获取从2到5的元素(结果是偏移为5、4、3和2的元素)
>>> S = 'abcdefg'
>>> S[5:1]
''
>>> S[5:1:-1]
'fedc'
像这样使用三重限制的列表来跳过或者反序输出是很常见的情况。
======================================================= ===================================
为什么要在意【分片】
如果在系统命令行中启动Python程序,有时会添加参数,这使用了内置的sys模块中的argv属性:
#File echo.py
import sys
print(sys.argv)
%python echo.py -a -b -c
['echo.py','-a','-b','-c']
通常只对跟随在程序后边的参数感兴趣。这就是一个分片的典型应用:一个分布表达式能够返回除了第一项之外的所有元素的列表。这里,sys.argv[1:]返回所期待的列表['-a','-b','-c']。
分片也常常用作清理输入文件的内容。如果知道一行将会以行终止字符(\n换行符标识)结束,你就能够通过一个简单的表达式,例如,line[:-1],把这行除了最后一个字符之外的所有内容提取出来。
不过,值得注意的是,为了去掉换行字符常常推荐采用line.rstrip方法,因为这个调用将会留下没有换行字符那行的最后一个字符。