Python索引和分片详解:
[开始:结束]:默认值为序列的开始和结束
索引值是指到要在那里“切下”
>>> S[0],S[-2]
('s', 'a')
>>> S = 'spam'
>>> S[0],S[-2] #索引
('s', 'a')
>>> S[1:3],S[1:],S[:-1] #分片
('pa', 'pam', 'spa')
因为在python中字符串被定义为字符的有序集合,所以我们能够通过其位置获取元素。Python中字符串中的字符是通过索引提取的,这时候你会获得字符串中在特定位置的一个字符。
索引(s[i])获取特定偏移的元素:
——第一个元素的偏移为0.
——负偏移意味着从最后或右边反向进行计数。
——S[0]获取第一个元素
——S[-2]获取倒数第二个元素(就像S[len(S)-2]一样)
python的偏移量是从0开始的,并且比字符串长度小1,负偏移量是从结束出反向计数。
分片:索引的一种通用形式,返回的是字符串的一部分,而不是单个项(能够让我们从整个字符串中提取一部分内容即子字符串)。
分片运作原理:
S[i:j]
——提取S的一部分作为一个序列。
——上边解并不包含在内,j为上边界,i为下边界
——分片的边界默认为0和序列的长度(如果没有明确给出)
——S[1:3] 获取从偏移为1的元素,直到但不包括偏移为3的元素
——S[1:] 获取从偏移为1的元素直到末尾(偏移序列长度)元素
——S[:3] 获取从偏移为0的元素直到但不包括偏移为3的元素
——S[:-1] 获取从偏移为0的元素直到但不包括最后一个元素之间的元素
——S[:] 获取从偏移为0的元素直到末尾的元素,实现了S的拷贝
扩展分片:第三限制值
python2.3中,分片表达式增加了一个可选的第三个索引,用作步进(stride),默认值为1.
>>> S = 'abcdefghijk'
>>> S[1:8:2]
'bdfh'
>>> S[::2]
'acegik'
>>>
完整形式的分片现在变为X[i:j:k],表示索引X对象中的元素,从偏移值i直到偏移值为j-1,每个k元素索引一次。k值默认为1.
也可以使用负数作步进:
>>> S = 'hello'
>>> S[::-1]
'olleh'
>>> S[::-2]
'olh'
-1步进表示分片会从右到左而不是通常的从左到右,实际效果就是实现了字符串的翻转。
通过一个负数步进,两个边界的意义实际上进行了反转。
也就是说:分片S[5:1:-1]以反的顺序获取从2到5的元素
>>> S = 'abcdefg'
>>> S[5:1:-1]
'fedc'
像这样使用三重限制列表实现跳过或反序输出很常见。
分片等同于用一个分片对象进行索引:
>>> 'spam'[1:3]
'pa'
>>> 'spam'[slice(1,3)]
'pa'
>>> 'spam'[::-1]
'maps'
>>> 'spam'[slice(None,None,-1)]
'maps'
字符串转换工具:
一个简单的例子:
在python中不能够让字符串和数字相加,甚至字符串看起来像数字也不可以:
>>> '42'+1
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: cannot concatenate 'str' and 'int' objects
>>> int('42')+1
43
>>> '42'+str(1)
'421'
>>>
这样设计是有意义的,因为“+”既能够作加法运算也能够进行字符串合并操作,这种转换的选择会变得模棱两可。因此Python会将其作为错误来处理。在上述例子中int函数将字符串转换为数字str函数将数字转换为字符串表达式。类似的内置函数也可以把浮点数转换为字符串,或把字符串转换为浮点数:
>>> str(3.1415),float('123')
('3.1415', 123.0)
字符串代码的转换:
同样是转换单个字符也可以通过将其传给内置的ord函数转换为对应的ASCII码——这个函数实际上返回的是这个字符在内存中对应字符的二进制值,chr函数将会执行相反的操作,获取ASCLL码将其转换为对应的字符:
>>> ord('s')
115
>>> chr(115)
's'
可以利用循环完成对字符串内所有字符的函数运算,这些工具也可以用来执行对字符串的数学运算。
例如:为了生成下一个字符,我们可以将当前字符串转换为整型,并进行如下数学运算:
>>> S = '5'
>>> S = chr(ord(S) + 1)
>>> S
'6'
修改字符串:
字符串在Python中具有不可变性——在创建后不能就地改变。就是不能在原地修改字符串。
>>> S = 'spam'
>>> S[0]
's'
>>> S[0] = 'x'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'str' object does not support item assignment
若要改变一个字符串需要利用合并、分片这样的工具建立并赋值给一个新的字符串,若是有必要的话可以将结果赋值给字符串最初的变量值。
>>> H = 'hello'
>>> H = H + 'HELLO'
>>> H
'helloHELLO'
>>> H = H[:4]+'world'+H[-1]
>>> H
'hellworldO'
replace也可以改变字符串:
>>> S = 'splot'
>>> S = S.replace('pl','pamal')
>>> S
'spamalot'
通过字符串格式化表达式来创建新的文本值:
>>> 'This is %d %s bird' % (1,'dead')
'This is 1 dead bird'
>>> 'This is %d %s bird!' % (1,'dead')
'This is 1 dead bird!'
>>> 'That is {0} {1} bird!'.format(1,'dead')
'That is 1 dead bird!'
上述这两种方式都是把对象替换为字符串,其实是将对象转换为字符串并且根据指定的格式来改变最初的字符串。
尽管用替换这个词,但是格式化的结果是一个新的字符串对象,而不是修改后的对象。
字符串方法:
1、字符串处理空格
strip是trim掉字符串两边的空格。
lstrip, trim掉左边的空格
rstrip, trim掉右边的空格
>>> line = ' The knights who say hi!\n'
>>> line
' The knights who say hi!\n'
>>> line.strip()
'The knights who say hi!'
>>> line.lstrip()
'The knights who say hi!\n'
>>> line.rstrip()
' The knights who say hi!'
strip lstrip rstrip使用方法
<span style="font-size:14px;">>>> S = 'saaaay yes no yaaaaaasss'
>>> S.strip('say')
' yes no '
</span>
S依次被去除首尾在['s','a','y']数组内的字符,直到字符在不数组内。所以,输出的结果为: yes no
比较简单吧,lstrip和rstrip原理是一样的。注意: 当没有传入参数时,是默认去除首尾空格的。
2、修改字符串
<span style="font-size:14px;">>>> S = 'spammy'
>>> S = S[:3]+'xx'+S[-1] #使用分片加索引来修改字符串
>>> S
'spaxxy'
>>> S.replace('xx','mm') #使用内置函数修改replace(old,new)
'spammy'
>>> S = 'xxxxSPAMxxxxSPAMxxxx' #find方法返回子字符串出现的偏移量(默认从前往后搜索,未找到返回-1)
>>> where = S.find('SPAM')
>>> where
4
>>> S = S[:where]+'EGGS'+S[(where+4):]
>>> S
'xxxxEGGSxxxxSPAMxxxx'</span>
<span style="font-size:14px;">>>> S
'xxxxEGGSxxxxSPAMxxxx'
>>> S = 'xxxxSPAMxxxxSPAMxxxx'
>>> S.replace('SPAM','EGGS') #注意replace每次返回的是一个新的字符串对象
'xxxxEGGSxxxxEGGSxxxx'
>>> S.replace('SPAM','EGGS',1)
'xxxxEGGSxxxxSPAMxxxx'
</span>
为了优化性能需要将字符串转化成一个支持原处修改的对象,内置list函数以任意序列中的元素创立一个新的列表,在这个例子中,list将字符串打散为一个列表,一旦字符串以这样的形式出现,就无需在每次修改之后进行复制就可以对其进行多次修改,修改之后如果需要将其变回一个字符串,可以用字符串方法jion将列表合并成一个字符串
:
<span style="font-size:14px;">>>> S = 'SPAM'
>>> L = list(S)
>>> L
['S', 'P', 'A', 'M']
>>> L[2],L[3]
('A', 'M')
>>> L[2] = 'a'
>>> S
'SPAM'
>>> L
['S', 'P', 'a', 'M']
>>> S =''.join(L) #<span style="color:#FF9966;">''空字符串作为分隔符(jion将列表字符串连接在一起并用分隔符分开)</span>
>>> S
'SPaM'
>>> 'SPAM'.join(['eggs','sausage','ham','toast'])<span style="color:#FF9966;">#'SPAM'作为字符串分隔符</span>
'eggsSPAMsausageSPAMhamSPAMtoast'
</span>
3、文本解析:
<span style="font-size:14px;">>>> line = 'aaa bbb ccc' #这组数据出现在固定偏移处可以用过分片技术
>>> line1 = line[:3]
>>> line2 = line[8:]
>>> line1,line2
('aaa', 'ccc')
>>> line.split() #split()方法将字符串分割为一个子字符串的列表,以分隔符为字符串分割标准,没有传递参数时默认分隔符为空格
['aaa', 'bbb', 'ccc']
>>> line = 'bob,hacker,30'
>>> line.split(',')
['bob', 'hacker', '30']
>>> line = "i'mSPAMaSPAMlumberjack" #分隔符也可以是字符串
>>> line.split('SPAM')
["i'm", 'a', 'lumberjack']
</span>
4、其他的字符串方法:
字符串中的大小写转换:
S.lower() #小写
S.upper() #大写
S.swapcase() #大小写互换
S.capitalize() #首字母大写
String.capwords(S) #这是模块中的方法。它把S用split()函数分开,然后用capitalize()把首字母变成大写,最后用join()合并到一起
>>> S = 'Hello'
>>> S.lower()
'hello'
>>> S.upper()
'HELLO'
>>> S.swapcase()
'hELLO'
>>> S = 'hello'
>>> S.capitalize()
'Hello'
>>> S = 'hello world'
字符串长度
<span style="font-weight: normal;">>>> S = 'hello world'
>>> len(S)</span>
追加指定长度的字符串、
<span style="font-weight: normal;">>>> Str1 = '12345'
>>> Str2 = 'abcdef'
>>> n = 3
>>> Str1 += Str2[0:n] #等价C中的 <span style="font-family: Arial, Tahoma, Verdana, sans-serif; font-size: 14px; color: rgb(51, 51, 51); line-height: 25px; ">strncat(sStr1,sStr2,n)</span></span>
扫描字符串是否包含指定的字符:
<span style="font-weight: normal;">>>> Str2 = '456'
>>> Str1 = '12345678'
>>> print len(Str1 and Str2)
3</span>
字符串指定长度比较:
<span style="font-weight: normal;">>>> Str1 = '12345'</span>
<span style="font-weight: normal;">>>> Str2 = '123bc'
>>> n = 3
>>> print cmp(Str1[0:n],Str2[0:n]) #返回值为0表示相等
0
>>> n = 4
>>> print cmp(Str1[0:n],Str2[0:n]) #返回值为-1表示不相等
-1</span>
复制指定长度的字符:
<span style="font-weight: normal;">>>> Str1 = ''
>>> Str2 = '12345'
>>> n = 3
>>> Str1 = Str2[0:n]
>>> print Str1
123</span>
将字符串前n个字符替换为指定的字符
>>> sStr1 = '12345'
>>> ch = 'r'
>>> n = 3
>>> sStr1 = n * ch + sStr1[3:] #字符串操作中+表示字符串链接,*表示重复
>>> print sStr1
rrr45
扫描字符串:
<span style="font-weight: normal;">>>> Str1 = 'cekjgdklab'
>>> Str2 = 'gka'
>>> Pos = -1</span>
<span style="font-weight: normal;">>>> for c in Str1:
... if c in Str2:
... Pos = Str1.index(c) #</span><span style="font-size: 14px; color: rgb(68, 68, 68); line-height: 23px; "><span style="font-weight: normal;">python 的index方法是在字符串里查找子串第一次出现的位置,类似字符串的find方法,不过比fi nd方法更好的是,如果查找不到子串,会抛出异常,而不是返回-1</span></span><span style="font-weight: normal;">
... break
...
>>> print Pos
2</span>
翻转字符串
<span style="font-weight: normal;">>>>Str1 = 'abcdefg'
>>>Str1 = Str1[::-1]
>>> print Str1
gfedcba</span>
查找字符串
<span style="font-weight: normal;">>>> Str1 = 'abcdefg'
>>> Str2 = 'cde'
>>> print Str1.find(Str2) #查找成功
2
>>> Str2 = 'cdm'
>>> print Str1.find(Str2) #查找失败
-1</span>
连接字符串
<span style="font-family:Arial, Tahoma, Verdana, sans-serif;">>>> mylist = ['Brazil', 'Russia', 'India', 'China']
>>> mylist = ','.join(mylist) #‘,’为链接字符串使用的分隔符
>>> mylist
'Brazil,Russia,India,China'
</span>
字符串在输出时的对齐
<span style="font-weight: normal;">S.ljust(width,[fillchar])
#输出width个字符,S左对齐,不足部分用fillchar填充,默认的为空格。
S.rjust(width,[fillchar]) #右对齐
S.center(width, [fillchar]) #中间对齐
S.zfill(width) #把S变成width长,并在右对齐,不足部分用0补足</span>
字符串中的搜索和替换
<span style="font-weight: normal;">S.find(substr, [start, [end]])
#返回S中出现substr的第一个字母的标号,如果S中没有substr则返回-1。start和end作用就相当于在S[start:end]中搜索
S.index(substr, [start, [end]])
#与find()相同,只是在S中没有substr时,会返回一个运行时错误(抛出异常)
S.rfind(substr, [start, [end]])
#返回S中最后出现的substr的第一个字母的标号,如果S中没有substr则返回-1,也就是说从右边算起的第一次出现的substr的首字母标号
S.rindex(substr, [start, [end]])
S.count(substr, [start, [end]]) #计算substr在S中出现的次数
S.replace(oldstr, newstr, [count])
#把S中的oldstar替换为newstr,count为替换次数。这是替换的通用形式,还有一些函数进行特殊字符的替换
S.strip([chars])
#把S中前后chars中有的字符全部去掉,可以理解为把S前后chars替换为None
S.lstrip([chars])
S.rstrip([chars])
S.expandtabs([tabsize])
#把S中的tab字符替换没空格,每个tab替换为tabsize个空格,默认是8个</span>
字符串的分割和组合
<span style="font-weight: normal;">S.split([sep, [maxsplit]])
#以sep为分隔符,把S分成一个list。maxsplit表示分割的次数。默认的分割符为空白字符
S.rsplit([sep, [maxsplit]])
S.splitlines([keepends])
#把S按照行分割符分为一个list,keepends是一个bool值,如果为真每行后而会保留行分割符。
S.join(seq) #把seq代表的序列──字符串序列,用S连接起来</span>
字符串的mapping,这一功能包含两个函数
<span style="font-weight: normal;">String.maketrans(from, to)
#返回一个256个字符组成的翻译表,其中from中的字符被一一对应地转换成to,所以from和to必须是等长的。
S.translate(table[,deletechars])
# 使用上面的函数产后的翻译表,把S进行翻译,并把deletechars中有的字符删掉。需要注意的是,如果S为unicode字符串,那么就不支持 deletechars参数,可以使用把某个字符翻译为None的方式实现相同的功能。此外还可以使用codecs模块的功能来创建更加功能强大的翻译表。</span>
字符串一对编码和解码的函数
<span style="font-weight: normal;">S.encode([encoding,[errors]])
# 其中encoding可以有多种值,比如gb2312 gbk gb18030 bz2 zlib big5 bzse64等都支持。errors默认值为"strict",意思是UnicodeError。可能的值还有'ignore', 'replace', 'xmlcharrefreplace', 'backslashreplace' 和所有的通过codecs.register_error注册的值。这一部分内容涉及codecs模块,不是特明白
S.decode([encoding,[errors]])</span>
字符串的测试、判断函数,这一类函数在string模块中没有,这些函数返回的都是bool值
<span style="font-weight: normal;">S.startswith(prefix[,start[,end]])
#是否以prefix开头
S.endswith(suffix[,start[,end]])
#以suffix结尾
S.isalnum()
#是否全是字母和数字,并至少有一个字符
S.isalpha() #是否全是字母,并至少有一个字符
S.isdigit() #是否全是数字,并至少有一个字符
S.isspace() #是否全是空白字符,并至少有一个字符
S.islower() #S中的字母是否全是小写
S.isupper() #S中的字母是否便是大写
S.istitle() #S是否是首字母大写的</span>
字符串类型转换函数,这几个函数只在string模块中有
<span style="font-weight: normal;">string.atoi(s[,base])
#base默认为10,如果为0,那么s就可以是012或0x23这种形式的字符串,如果是16那么s就只能是0x23或0X12这种形式的字符串
string.atol(s[,base]) #转成long
string.atof(s[,base]) #转成float</span>
这里再次强调,字符串对象是不可改变的,也就是说在python创建一个字符串后,你不能把这个字符中的某一部分改变。任何上面的函数改变了字符串后,都会返回一个新的字符串,原字串并没有变。其实这也是有变通的办法的,可以用S=list(S)这个函数把S变为由单个字符为成员的list,这样的话就可以使用S[3]='a'的方式改变值,然后再使用S=" ".join(S)还原成字符串
<span style="font-size:14px; ">>>> S = 'SPAM'
>>> L = list(S)
>>> L
['S', 'P', 'A', 'M']
>>> L[2],L[3]
('A', 'M')
>>> L[2] = 'a'
>>> S
'SPAM'
>>> L
['S', 'P', 'a', 'M']
>>> S =''.join(L) #<span style="color:#FF9966;">''空字符串作为分隔符(jion将列表字符串连接在一起并用分隔符分开)</span>
>>> S
'SPaM'
>>> 'SPAM'.join(['eggs','sausage','ham','toast'])<span style="color:#FF9966;">#'SPAM'作为字符串分隔符</span>
'eggsSPAMsausageSPAMhamSPAMtoast'</span>
字符串格式化表达式:
格式化符号 | 说明 |
---|---|
%c | 转换成字符(ASCII 码值,或者长度为一的字符串) |
%r | 优先用repr()函数进行字符串转换(Python2.0新增) |
%s | 优先用str()函数进行字符串转换 |
%d / %i | 转成有符号十进制数 |
%u | 转成无符号十进制数 |
%o | 转成无符号八进制数 |
%x / %X | (Unsigned)转成无符号十六进制数(x / X 代表转换后的十六进制字符的大 小写) |
%e / %E | 转成科学计数法(e / E控制输出e / E) |
%f / %F | 转成浮点数(小数部分自然截断) |
%g / %G | %e和%f / %E和%F 的简写 |
%% | 输出% |
当然,还有一些辅助符号,如下表所示:
辅助符号 | 说明 |
---|---|
* | 定义宽度或者小数点精度 |
- | 用做左对齐 |
+ | 在正数前面显示加号(+) |
<sp> | 在正数前面显示空格 |
# | 在八进制数前面显示零(0),在十六进制前面显示“0x”或者“0X”(取决于用的是“x”还是“X”) |
0 | 显示的数字前面填充“0”而不是默认的空格 |
m.n | m 是显示的最小总宽度,n 是小数点后的位数(如果可用的话) |
注意:辅助符号要在百分号(%)和格式化符号之间。
Python提供了一种高级的字符串处理任务——字符串格式化:允许在一个单个的步骤中对一个字符串执行多个特定类型的替换。
字符串格式化可以以两种形式实现:
1、字符串格式化表达式:这是从Python诞生的时候就有的最初技术,是基于C语言的printf模型,并且在大多数现有的代码中使用;
字符串格式化表达式格式化字符串方法:
1)、在%操作符左侧放置一个需要进行格式化的字符串,这个字符串带有一个或多个嵌入的转换目标,都已%开头(eg:%d)
2)、在%在操作符右侧放置一个(或多个,嵌入到元组中)对象,这些对象将会插入到左侧想让Python进行格式化字符串的一个或多个转换目标的位置上。
<span style="color:#000000;">>>> exclamation = "Ni"
>>> "The Knights who say %s !" % exclamation
'The Knights who say Ni !'
>>> "%d %s %d you" % (1,'spam',4)
'1 spam 4 you'
>>> "%s -- %s -- %s" % (42,3.14159,[1,2,3]) #所有左侧目标都是%s,表示把他们都转换成字符串(</span><span style="color:#FF0000;">除非作特殊格式化,一般记得用%s格式化代 码就可)</span><span style="color:#000000;">
'42 -- 3.14159 -- [1, 2, 3]'</span>
注意:不止一个值待插入的时候应该在右侧用括号把他们括起来(也就是说把他们放到元组中)——%格式化表达式操作符在其右边期待一个单独的项或多个项的元组。
由于字符串是不可变的,格式化总是返回新的字符串作为结果而不是对左侧字符串的修改,如果需要的华,可以分配一个变量名来保存结果。
转换目标的通用结构:
%[(name)[flags][width][.precision]] typecode
>>> x = 1234
>>> res = "integers:...%d...%-6d...%06d" % (x,x,x) #罗列出左对齐(-),补零(0)标志位:%-6d :6位左对齐,%06d:6位补零
>>> res
'integers:...1234...1234 ...001234'
>>> x = 1.23456789
>>> x
1.2345678899999999
>>> '%-6.2f | %05.2f | %+06.1f' % (x,x,x)
'1.23 | 01.23 | +001.2'
基于字典的字符串格式化:
字符串格式化的同时允许左边的转换目标来引用右边字典中的键提取对应的值:
>>> "%(n)d,%(x)s" % {"n":1,"x":"spam"}
'1,spam'
上述例子中格式化字符串里面(n),(x)引用了右边字典中的键,并提取他们相应的值,生成类似HTML和XML的程序往往利用这一技术。可以建立一个数值字典,利用基于键的格式化表达式一次性替换。
>>> reply = '''Greetings...
... Hello %(name)s!
... You age squared is %(age)s
... '''
>>> values = {'name':'Bob' , 'age':40}
>>> print(reply%values)
Greetings...
Hello Bob!
You age squared is 40
这样的小技巧也常与内置函数vars配合使用,这个函数返回的字典包含了所有在本函数调用时存在的变量
2、字符串格式化方法调用:这是在Python 2.6 和Python 3.0 中曾加的技术,是Python独有的技术,和字符串格式化表达式功能有很大的重叠;
字符串格式化调用方法使用字符串对象的format方法,使用主体字符串作为模板,并且接受任意多个表示将要根据模板替换值的参数。在主题字符串中,花括号通过位置或关键字指出替换目标及将要插入的参数。
>>> template = '{0},{1} and {2}' #by position
>>> template.format('spam','ham','eggs')
'spam,ham and eggs'
>>> template = '{name},{age} and {food}' #by keyword
>>> template.format(name='Bob',age=40,food='eggs')
'Bob,40 and eggs'
>>> template = '{name},{0} and {food}' #by both
>>> template.format(40,name='Bob',food='eggs')
'Bob,40 and eggs'
字符串也可以是一个临时字符串常量:
>>> '{name},{0} and {food}'.format(40,name='Bob',food='eggs')
'Bob,40 and eggs'
参考:Python学习手册
http://www.jb51.net/article/47956.htm