这篇文章主要介绍python当中用的非常多的一种内置类型——str。它属于python中的Sequnce Type(序列类型)。python中一共7种序列类型,分别为str(字符串),unicode(u字符串),list(列表),tuple(元组),bytearray(字节数组),buffer(缓冲内存),xrange(范围)。它们的通用操作如下:
Operation | Result |
---|---|
x in s | 判断x是否在s中 |
x not in s | 判断x是不在s中 |
x + t | 两个序列合并, 将t加到s之后 |
s * n, n * s | 相当于n个s相加 |
s[i] | 返回索引值i所对应的值 |
s[i: j] | 判断x是否在s中 |
s[i: j: k] | 切片操作,步长为k |
len(s) | 返回序列s的长度 |
min(s) | 返回序列s中的最小值 |
max(s) | 返回序列s中的最大值 |
s.index(x) | 返回x的第一个序列值在s中的索引值 |
s.count(x) | 返回s中x一共出现的次数 |
以上的操作对所有的序列类型都适用,其中有一些注意点,可以参考python2.7.8官方文档。下面的内容就开始介绍str。
1. 字符编码问题
1.1 基本概念
在讲python中的字符编码问题之前,我想你非常有必要把ascii, unicode, 以及编码方式如utf-8等这些概念搞清楚,否则继续看下面的内容会一头雾水。这方面的资料网上整理的很多,这里主要列一些觉得讲的不错的:
相信聪明的你读了上面的这些文章,一定对什么是ascii,什么是unicode,什么是编码方式有了一定的认识。什么,你说你不明白!--!那我简单的解释下好了,ascii是一种只表示英文的字符集,并且在计算机中只用一个字节来表示一个字符。而unicode是一种能够表示全世界所有字符的字符集,至于它在计算中用几个字节,用什么字节来表示,根据具体的编码方式的不同而不同。比如最常见的utf-8,gb2312等等。
我们知道计算机无论是在保存文件,还是网络上的传输文件都是以字节的形式发生的。而我们在程序当中处理字符串或者文件不可能处理那些看不懂的字节,所以就存在两个问题:
- 将字符串以某种方式编码(encode)成为字节以进行保存或者传输
- 将编程后的字节再以编码的方式解码(decode)成为我们能够看得懂并且能够处理的字符串
带着上面的两个问题,我们再来看看python2.x当中是怎么处理上面的两个问题的。
1.2 python中的str与unicode
python中的str与unicode
- str类型,它事实上是字符串的字节表示,使用的编码方式是当前系统的默认编 码方式,可以通过函数
locale.getdefaultlocale()
来查看 - unicode类型,它是真正意义上的字符串,保存的内容是一个个字符的unicode代码,使用前缀
\u
来标识。
可以通过下面的代码看的比较清楚:
>>> s = "下雪"
>>> s
‘\xcf\xc2\xd1\xa9‘ #十六进制的字节表示方法
>>> u = unicode(s, "cp936") #我的电脑上默认的是cp936编码方式
>>> u
u‘\u4e0b\u96ea‘ #unicode字符表示方法
>>> type(s), type(u)
(<type ‘str‘>, <type ‘unicode‘>)
>>>
1.3 decode()与encode()方法
decode()方法将str(字节形式)解码成为unicode形式
- 输入的decode的解码方式必须是str的编码方式,否则将出错
- 如果不输入解码方式,将默认的采用
sys.defaultencoding()
方式解码,一般为ASCII方式。这个时候,如果str表示的是英文或者标点之类的,将不会引起错误,如果str中存在中文,等将会引起解码错误(ascii不能解码中文)。
示例的代码如下:
>>> print s.decode() #采用ascii解码
snow
>>> print s.decode("cp936") #采用cp936解码
snow
>>> s = "下雪"
>>> print s.decode("cp936")
下雪
>>> print s.decode("utf-8") #解码方式不对,引起错误
Traceback (most recent call last):
File "<pyshell#48>", line 1, in <module>
print s.decode("utf-8")
File "C:\Python27\lib\encodings\utf_8.py", line 16, in decode
return codecs.utf_8_decode(input, errors, True)
UnicodeDecodeError: ‘utf8‘ codec can‘t decode byte 0xcf in position 0: invalid continuation byte
>>> print s.decode() #ascii不能解释中文,引起错误
Traceback (most recent call last):
File "<pyshell#49>", line 1, in <module>
print s.decode()
UnicodeDecodeError: ‘ascii‘ codec can‘t decode byte 0xcf in position 0: ordinal not in range(128)
>>>
encode()方法将unicode形式以某种编码方式编码成为str(字节形式)
- 这个方法将unicode字符串编码成为str(字节形式)。输入的参数表示编码方式,比如"cp936", "utf-8", "gbk"等等。
- 如果不输入参数表示系统默认的编码方式,一般为ascii。当编码中文时,采用ascii将会产生错误。
示例代码如下:
>>> s = "下雪"
>>> u = s.decode("cp936") #解码
>>> print u.encode("cp936") #编码
下雪
>>> print u.encode("utf-8") #以utf-8编码
涓嬮洩
>>> print u.encode("gb2312") #以gb2312编码
下雪
>>> print u.encode("gbk") #以gbk编码
下雪
>>> print u.encode() #以ascii编码,产生错误
Traceback (most recent call last):
File "<pyshell#59>", line 1, in <module>
print u.encode()
UnicodeEncodeError: ‘ascii‘ codec can‘t encode characters in position 0-1: ordinal not in range(128)
>>>
希望以上的代码,对你理解encode()方法会有一些帮助。不过你也许好奇,为什么以utf-8编码的字符串输出的时候,会是乱码呢??其实这个是跟控制台的编码方式有关,只有当它跟字符串的编码方式一致时,才会正常显示。
1.4 str的encode()方法,unicode的decode()方法
关于这两个方法,不想详细的阐述了,因为我觉得它们没有太多的用途。只做以下的说明:
str.encode("encodeway")
<==>str.decode().encode("encodeway")
unicode.decode("decodeway")
<==>unicode.encode().decode("decodeway")
从unicode到unicode,本身就没什么意义!!
由于这篇文章的重点不是放在python中的编码上的,所以只能做简略的说明。网上对这部分整理的资料也很多,这里就简单的列举一些我感觉写的不错的:
2. str的格式
在python中,通常有两种控制字符串格式的方式。第一就是古老的,许多其他语言如C中使用的格式控制符;第二个方法就是format方法。这里不多的介绍,可以参考以下的两个博文。其中第一个主要讲格式控制符,第二个讲format方法。
3. str常用方法
s.center(width[, fillchar])
返回字符串是将s作为中间字符串的方式并扩展到width长度,两端使用fillchar填充,默认以空格填充。 example :
>>> s = "love"
>>> s.center(8, "_")
‘__love__‘
>>>
s.find(sub[, start[, end]])
返回s中子字符串sub的第一个索引值,start, end为可选参数,表示索引位置的起始与结束位置,如果找不到返回-1。find方法用在你确定知道sub存在在s中,否则应该使用 sub in s
操作。example :
s = "http://www.baidu.com"
>>> s.find("w", 1, -1)
7
>>>
s.index(sub[, start[, end]])
与find方法类似,只不过如果找不到sub的话,引起ValueError错误
s.count(sub[start[, end]])
返回s中sub子字符串出现的次数
s.isspace()
如果s由空格字符所组成,则返回True。 如果s为空字符串,或者s中存在不是空格的字符串则返回False。 注意,s由空格字符串组成的话,bool(s)为True, s是空字符串的话,bool(s)为False
s.join(iterable)
将s加入到iterable中每两个元素之间,并将结果返回。其中iterable表示可以进行迭代的数据类型,如list, tuple等。要求就是其中的元素可以与字符串s进行 += 操作。example :
>>> s = "love"
>>> s.join("you")
‘yloveoloveu‘
>>>
s.ljust(width[, fillchar])
与s.center()
方法类似,只不过在字符串s左边进行操作。
s.strip([chars])
从字符串s两边开始,凡是出现在chars中的字符全部移除,直到出现第一个不在chars中的字符处终止操作。如果不传入chars,默认移除空格。example :
>>> s = " hello world "
>>> s.strip()
‘hello world‘
>>>
s. partition(seq)
反之值为三个元素的元组,第一个表示seq序列之前的字符串,第二个表示seq序列,第三个表示剩余的字符串。如果s中找不到seq,返回(s, ‘‘, ‘‘)
s.replace(old, new[, count])
返回s的副本,其中用new取代了old,可选参数count表示取代的次数。
s.split([seq[, maxsplit]])
将s的副本按照seq作为分割字符,分裂成一个个元素,并组成一个列表返回。 seq没有给出的话,默认按照空格字符分割,maxsplit表示分割的最大次数。 example :
>>> s = "function_calculate_sum"
>>> s.split("_")
[‘function‘, ‘calculate‘, ‘sum‘]
>>>
s.splitlines([keepends])
在s中表示换行的字符("\n" 或者 "\r\n")地方将s分割成一个个元素,并组成一个列表返回,如果keepends传入True的话,表示保留换行字符。
For example, ab c\n\nde fg\rkl\r\n‘.splitlines()
returns [‘ab c‘, ‘‘, ‘de fg‘, ‘kl‘]
, while the same call with splitlines(True)
returns [‘ab c\n‘, ‘\n‘, ‘de fg\r‘, ‘kl\r\n‘]
.
注意点 :
- 以上字符串操作都是在原本字符串的副本上进行的,不会改变原来字符串的值
- 有些函数会有"左版本" 与 "右版本",分别在原来的函数名的基础上加上了‘l‘或者‘r‘,实现的功能类似。
- 更加详细的方法描述,可以参考官方文档。
ok!关于python中最入门的字符串跟列表的基础知识先整理到这里。再接再厉!! 另外以下是一道leetcode上的练习题,主要用到字符串跟列表的一些操作,有兴趣的同学可以练练!!
Exercise: Reverse Words in a String