python字符串编码
python字符串、字符串处理函数及字符串相关操作
python字符串表示
Python除处理数字外还可以处理字符串,字符串用单撇号或双撇号包裹:>>> 'spam eggs'
'spam eggs'
>>> 'doesn/'t'
"doesn't"
>>> "doesn't"
"doesn't"
>>> '"Yes," he said.'
'"Yes," he said.'
>>> "/"Yes,/" he said."
'"Yes," he said.'
>>> '"Isn/'t," she said.'
'"Isn/'t," she said.'
字符串输出格式与输入的样子相同,都是用撇号包裹,撇号和其它特殊字符用用反斜杠转义。如果字符串中有单撇号而没有双撇号则用双撇号包裹,否则应该用单撇号包裹。后面要介绍的print语句可以不带撇号或转义输出字符串。
多行的长字符串也可以用行尾反斜杠续行,续行的行首空白不被忽略,如
hello = "This is a rather long string containing/n several lines of text just as you would do in C./n Note that whitespace at the beginning of the line is significant./n"
print hello
结果为
This is a rather long string containing
several lines of text just as you would do in C.
Note that whitespace at the beginning of the line is significant.
对于特别长的字符串(比如包含说明的几段文字),如果用上面的方式每行都用/n/结尾是很麻烦的,特别是这样无法用象Emacs这样的功能强大的编辑器重新编排。对这种情况,可以使用三重撇号,例如
hello = """
This string is bounded by triple double quotes (3 times ").
Unescaped newlines in the string are retained, though it is still possible/nto use all normal escape sequences.
Whitespace at the beginning of a line is
significant. If you need to include three opening quotes
you have to escape at least one of them, e.g. /""".
This string ends in a newline.
"""
三重撇号字符串也可以用三个单撇号,没有任何语义差别。
多行的字符串常量可以直接连接起来,字符串常量之间用空格分隔则在编译时可以自动连接起来,这样可以把一个长字符串连接起来而不需要牺牲缩进对齐或性能,不象用加号连接需要运算,也不象字符串串内的换行其行首空格需要保持。
字符串连接和重复
字符串可以用+号连接起来,用*号重复:
>>> word = 'Help' + 'A'
>>> word
'HelpA'
>>> '<' + word*5 + '>'
'<HelpAHelpAHelpAHelpAHelpA>'
字符串连接的几种不同方式
def concat1():
z = x + y
return z
def concat2():
z = "%s%s" % (x, y)
return z
def concat3():
z = "{}{}".format(x, y)
return z
def concat4():
z = "{0}{1}".format(x, y)
return z
[Python中实现快速字符串连接]
字符串索引
字符串可以象在C中那样用下标索引,字符串的第一个字符下标为0。
Python没有单独的字符数据类型,一个字符就是长度为一的字符串。象在Icon语言中那样,可以用片段(slice)记号来指定子串,片段即用冒号隔开的两个下标。
>>> word[4]
'A'
>>> word[0:2]
'He'
>>> word[2:4]
'lp'
片段有很好的缺省值:第一下标省略时缺省为零,第二下标省略时缺省为字符串的长度。
>>> word[:2] # 前两个字符
'He'
>>> word[2:] # 除前两个字符串外的部分
'lpA'
注意s[:i] + s[i:] 等于 s 是片段运算的一个有用的恒等式。
>>> word[:2] + word[2:]
'HelpA'
>>> word[:3] + word[3:]
'HelpA'
不合理的片段下标可以很好地得到解释:过大的下标被换成字符串长度,上界小于下界时返回空串。
>>> word[1:100]
'elpA'
>>> word[10:]
''
>>> word[2:1]
''
下标允许为负数,这时从右向左数。例如:
>>> word[-1] # 最后一个字符
'A'
>>> word[-2] # 倒数第二个字符
'p'
>>> word[-2:] # 最后两个字符
'pA'
>>> word[:-2] # 除最后两个字符外的部分
'Hel'
但要注意的是 -0 实际还是 0,所以它不会从右向左数!
>>> word[-0] # (因为 -0 等于 0)
'H'
超出范围的片段下标被截断,但在非片段的情况下不要这样:
>>> word[-100:]
'HelpA'
>>> word[-10] # 错误
Traceback (innermost last):
File "<stdin>", line 1
IndexError: string index out of range
记住片段意义的最好方法是把下标看成是字符 之间的点,第一个字符的左边界号码为0。有n个字符的字符串的最后一个字符的右边界下标为n,例如:
+---+---+---+---+---+
| H | e | l | p | A |
+---+---+---+---+---+
0 1 2 3 4 5
-5 -4 -3 -2 -1
第一行数字给出字符串中下标0到5的位置,第二行给出相应的负下标。从i到j的片段由在边界i和j之间的字符组成。
对于非负下标,如果下标都在界内,则片段的长度为下标的差。例如,word[1:3] 的长度为 2。
字符串的分片
定义一个字符串以后,我们可以截取其中的任意部分形成新串。这种操作被称作字符串的分片(slice)。字符串分片跟列表的分片(slicing lists)原理是一样的,从直观上也说得通,因为字符串本身就是一些字符序列。
>>> a_string = "My alphabet starts where your alphabet ends."
>>> a_string[3:11]
"alphabet"
>>> a_string[3:-3]
"alphabet starts where your alphabet en"
>>> a_string[0:2]
"My"
>>> a_string[:18]
"My alphabet starts"
>>> a_string[18:]
" where your alphabet ends."
-
我们可以通过指定两个索引值来获得原字符串的一个slice。该操作的返回值是一个新串,依次包含了从原串中第一个索引位置开始,直到但是不包含第二个索引位置之间的所有字符。
-
就像给列表做分片一样,我们也可以使用负的索引值来分片字符串。
-
字符串的下标索引是从0开始的,所以a_string[0:2]会返回原字符串的前两个元素,从a_string[0]开始,直到但不包括a_string[2]。
-
如果省略了第一个索引值,Python会默认它的值为0。所以a_string[:18]跟a_string[0:18]的效果是一样的,因为从0开始是被Python默认的。
-
同样地,如果第2个索引值是原字符串的长度,那么我们也可以省略它。所以,在此处a_string[18:]跟a_string[18:44]的结果是一样的,因为这个串的刚好有44个字符。这种规则存在某种有趣的对称性。在这个由44个字符组成的串中,a_string[:18]会返回前18个字符,而a_string[18:]则会返回除了前18个字符以外字符串的剩余部分。事实上a_string[:n]总是会返回串的前n个字符,而a_string[n:]则会返回其余的部分,这与串的长度无关。
字符串长度
内置函数len()返回字符串的长度:
>>> s = 'supercalifragilisticexpialidocious'
>>> len(s)
34
Python内置的字符串处理函数
python字符串子串
python没有substring函数,因为直接使用str[start:end]就可以啦。
字母处理
全部大写:str.upper()全部小写:str.lower()
大小写互换:str.swapcase()
首字母大写,其余小写:str.capitalize()
首字母大写:str.title()
print '%s lower=%s' % (str,str.lower())
print '%s upper=%s' % (str,str.upper())
print '%s swapcase=%s' % (str,str.swapcase())
print '%s capitalize=%s' % (str,str.capitalize())
print '%s title=%s' % (str,str.title())
格式化相关
获取固定长度,右对齐,左边不够用空格补齐:str.ljust(width)获取固定长度,左对齐,右边不够用空格补齐:str.ljust(width)
获取固定长度,中间对齐,两边不够用空格补齐:str.ljust(width)
获取固定长度,右对齐,左边不足用0补齐
print '%s ljust=%s' % (str,str.ljust(20))
print '%s rjust=%s' % (str,str.rjust(20))
print '%s center=%s' % (str,str.center(20))
print '%s zfill=%s' % (str,str.zfill(20))
字符串搜索相关
搜索指定字符串,没有返回-1:str.find('t')
python字符串查找指定多个子字符串的所有位置:
a = "dhvka,feovj.dlfida?dfka.dlviaj,dlvjaoid,vjaoj?"
b = [i for i, j in enumerate(a) if j in [',', '.', '?']]
print(b)
[5, 11, 18, 23, 30, 39, 45]
指定起始位置搜索:str.find('t',start)指定起始及结束位置搜索:str.find('t',start,end)
从右边开始查找:str.rfind('t')
搜索到多少个指定字符串:str.count('t')
上面所有方法都可用index代替,不同的是使用index查找不到会抛异常,而find返回-1
print '%s find nono=%d' % (str,str.find('nono'))
print '%s find t=%d' % (str,str.find('t'))
print '%s find t from %d=%d' % (str,1,str.find('t',1))
print '%s find t from %d to %d=%d' % (str,1,2,str.find('t',1,2))
#print '%s index nono ' % (str,str.index('nono',1,2))
print '%s rfind t=%d' % (str,str.rfind('t'))
print '%s count t=%d' % (str,str.count('t'))
python判断字符串是否包含子串的方法
1. if 'abcde'.__contains__("abc")
2. if "abc" in 'abcde'
3.'abcde'.find('bcd') >= 0
4.'abcde'.count('bcd') > 0
5.try:
string.index(ls,ss)
print 'find it'
except(ValueError):
print 'fail'
[http://blog.csdn.net/elvis_kwok/article/details/7405083]
[Python字符串操作]字符串替换相关
替换old为new:str.replace('old','new')替换指定次数的old为new:str.replace('old','new',maxReplaceTimes)
print '%s replace t to *=%s' % (str,str.replace('t', '*'))
print '%s replace t to *=%s' % (str,str.replace('t', '*',1))
字符串一次替换多个不同字符
将字符串中的[ ] '替换成空格
methon1: tags = re.sub("
methon3: [一次完成多个字符串的替换]
字符串去空格及去指定字符
去两边空格:str.strip()去左空格:str.lstrip()
去右空格:str.rstrip()
去两边字符串(支持正则):s.strip('{|}')
按指定字符分割字符串为数组:str.split(' ')默认按空格分隔
指定分隔符str,str.split('-')
字符串判断相关
是否以start开头:str.startswith('start')是否以end结尾:str.endswith('end')
是否全为字母或数字:str.isalnum()
是否全字母:str.isalpha()
是否全数字:str.isdigit()
是否全小写:str.islower()
是否全大写:str.isupper()
str='python String function'
字符串相关操作
repr(反引号)操作
在Python 2里,为了得到一个任意对象的字符串表示,有一种把对象包装在反引号里(比如`x`)的特殊语法。在Python 3里,这种能力仍然存在,但是你不能再使用反引号获得这种字符串表示了。你需要使用全局函数repr()。
Notes | Python 2 | Python 3 |
---|---|---|
① | `x` | repr(x) |
② | `'PapayaWhip' + `2`` | repr('PapayaWhip'+ repr(2)) |
- 记住,x可以是任何东西 — 一个类,函数,模块,基本数据类型,等等。repr()函数可以使用任何类型的参数。
- 在Python 2里,反引号可以嵌套,导致了这种令人费解的(但是有效的)表达式。2to3足够智能以将这种嵌套调用转换到repr()函数。
字符串分割
使用多个界定符分割字符串
string对象的 split() 方法只适应于非常简单的字符串分割情形,它并不允许有多个分隔符或者是分隔符周围不确定的空格。当你需要更加灵活的切割字符串的时候,最好使用re.split() 方法:
>>> line = 'asdf fjdk; afed, fjek,asdf, foo'
>>> import re
>>> re.split(r'[;,\s]\s*', line)
['asdf', 'fjdk', 'afed', 'fjek', 'asdf', 'foo']
s = 'Hello!This?Is!What?I!Want'
for i in ('!', '?'):
s = s.replace(i,' ')
list1 = s.split()
解决方案3:
my_split(s, ['!', '?'])
格式化字符串
自python2.6开始,新增了一种格式化字符串的函数str.format(),可谓威力十足。跟之前的%型格式化字符串相比是优越的存在。
语法
它通过{}和:来代替%。
“映射”示例
通过位置
In [1]: '{0},{1}'.format('kzc',18)
Out[1]: 'kzc,18'
In [2]: '{},{}'.format('kzc',18)
Out[2]: 'kzc,18'
In [3]: '{1},{0},{1}'.format('kzc',18)
Out[3]: '18,kzc,18'
字符串的format函数可以接受不限个参数,位置可以不按顺序,可以不用或者用多次,不过2.6不能为空{},2.7才可以。
通过关键字参数
In [5]: '{name},{age}'.format(age=18,name='kzc')
Out[5]: 'kzc,18'
通过对象属性
class Person:
def __init__(self,name,age):
self.name,self.age = name,age
def __str__(self):
return 'This guy is {self.name},is {self.age} old'.format(self=self)
In [2]: str(Person('kzc',18))
Out[2]: 'This guy is kzc,is 18 old'
通过下标
In [7]: p=['kzc',18]
In [8]: '{0[0]},{0[1]}'.format(p)
Out[8]: 'kzc,18'
有了这些便捷的“映射”方式,我们就有了偷懒利器。基本的python知识告诉我们,list和tuple可以通过“打散”成普通参数给函数,而dict可以打散成关键字参数给函数(通过和*)。所以可以轻松的传个list/tuple/dict给format函数。非常灵活。
格式限定符
它有着丰富的的“格式限定符”(语法是{}中带:号),比如:
填充与对齐
填充常跟对齐一起使用
^、<、>分别是居中、左对齐、右对齐,后面带宽度;:号后面带填充的字符,只能是一个字符,不指定的话默认是用空格填充。
比如
In [15]: '{:>8}'.format('189')
Out[15]: ' 189'
In [16]: '{:0>8}'.format('189')
Out[16]: '00000189'
In [17]: '{:a>8}'.format('189')
Out[17]: 'aaaaa189'
print('{:*^60}'.format(' 每个TERMINALNO 数据记录数 '))
******************** 每个TERMINALNO 数据记录数 ******************** (中文字符居然只算1个字符,所以有中文字符时候输出不同行还是对不齐)
Note: 如果是使用{:>20}格式化列表,要先将列表转化成str(),否则报错TypeError: unsupported format string passed to list.__format__.
精度与类型f
精度常跟类型f一起使用
In [44]: '{:.2f}'.format(321.33345)
Out[44]: '321.33'
其中.2表示长度为2的精度,f表示float类型。
其他类型
主要就是进制了,b、d、o、x分别是二进制、十进制、八进制、十六进制。
In [54]: '{:b}'.format(17)
Out[54]: '10001'
In [55]: '{:d}'.format(17)
Out[55]: '17'
In [56]: '{:o}'.format(17)
Out[56]: '21'
In [57]: '{:x}'.format(17)
Out[57]: '11'
设置二进制输出位宽:32位输出,前面不足的补0。
print('{:032b}'.format(i)) # bin(i)
用,号还能用来做金额的千位分隔符。
In [47]: '{:,}'.format(1234567890)
Out[47]: '1,234,567,890'
【http://blog.csdn.net/handsomekang/article/details/9183303】
格式化字符串
字符串可以使用单引号或者双引号来定义。我们再来看一看humansize.py:
SUFFIXES = {1000: ["KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"], 1024: ["KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"]}def approximate_size(size, a_kilobyte_is_1024_bytes=True): """Convert a file size to human-readable form. Keyword arguments: size -- file size in bytes a_kilobyte_is_1024_bytes -- if True (default), use multiples of 1024 if False, use multiples of 1000 Returns: string """ if size < 0: raise ValueError("number must be non-negative") multiple = 1024 if a_kilobyte_is_1024_bytes else 1000 for suffix in SUFFIXES[multiple]: size /= multiple if size < multiple: return "{0:.1f} {1}".format(size, suffix) raise ValueError("number too large")
-
"KB", "MB", "GB"… 这些是字符串。
-
函数的文档字符串(docstring)也是字符串。当前的文档字符串占用了多行,所以它使用了相邻的3个引号来标记字符串的起始和终止。
-
这3个引号代表该文档字符串的终止。
-
这是另外一个字符串,作为一个可读的提示信息传递给异常。
-
瓦哦…那是什么?
Python 3支持把值格式化(format)成字符串。可以有非常复杂的表达式,最基本的用法是使用单个占位符(placeholder)将一个值插入字符串。
>>> username = "mark"
>>> password = "PapayaWhip"
>>> "{0}"s password is {1}".format(username, password)
"mark"s password is PapayaWhip"
-
不,PapayaWhip真的不是我的密码。
-
这里包含了很多知识。首先,这里使用了一个字符串字面值的方法调用。字符串也是对象,对象则有其方法。其次,整个表达式返回一个字符串。最后,{0}和{1}叫做替换字段(replacement field),他们会被传递给format()方法的参数替换。
复合字段名
在前一个例子中,替换字段只是简单的整数,这是最简单的用法。整型替换字段被当做传给format()方法的参数列表的位置索引。即,{0}会被第一个参数替换(在此例中即username),{1}被第二个参数替换(password),&c。可以有跟参数一样多的替换字段,同时你也可以使用任意多个参数来调用format()。但是替换字段远比这个强大。
>>> import humansize
>>> si_suffixes = humansize.SUFFIXES[1000]
>>> si_suffixes
["KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"]
>>> "1000{0[0]} = 1{0[1]}".format(si_suffixes)
"1000KB = 1MB"
-
不需要调用humansize模块定义的任何函数我们就可以抓取到其所定义的数据结构:国际单位制(SI, 来自法语Système International)的后缀列表(以1000为进制)。
-
这一句看上去有些复杂,其实不是这样的。{0}代表传递给format()方法的第一个参数,即si_suffixes。注意si_suffixes是一个列表。所以{0[0]}指代si_suffixes的第一个元素,即"KB"。同时,{0[1]}指代该列表的第二个元素,即:"MB"。大括号以外的内容 -- 包括1000,等号,还有空格等 -- 则按原样输出。语句最后返回字符串为"1000KB = 1MB"。
这个例子说明格式说明符可以通过利用(类似)Python的语法访问到对象的元素或属性。这就叫做复合字段名(compound field names)。以下复合字段名都是有效的。
-
使用列表作为参数,并且通过下标索引来访问其元素(跟上一例类似)
-
使用字典作为参数,并且通过键来访问其值
-
使用模块作为参数,并且通过名字来访问其变量及函数
-
使用类的实例作为参数,并且通过名字来访问其方法和属性
-
以上方法的任意组合
为了使你确信的确如此,下面这个样例就组合使用了上面所有方法:
>>> import humansize
>>> import sys
>>> "1MB = 1000{0.modules[humansize].SUFFIXES[1000][0]}".format(sys)
"1MB = 1000KB"
下面是描述它如何工作的:
-
sys模块保存了当前正在运行的Python实例的信息。由于已经导入了这个模块,因此可以将其作为format()方法的参数。所以替换域{0}指代sys模块。
-
sys.modules is a dictionary of all the modules that have been imported in this Python instance. The keys are the module names as strings; the values are the module objects themselves. So the replacement field{0.modules} refers to the dictionary of imported modules.sys.modules是一个保存当前Python实例中所有已经导入模块的字典。模块的名字作为字典的键;模块自身则是键所对应的值。所以{0.modules}指代保存当前己被导入模块的字典。
-
sys.modules["humansize"]即刚才导入的humansize模块。所以替换域{0.modules[humansize]}指代humansize模块。请注意以上两句在语法上轻微的不同。在实际的Python代码中,字典sys.modules的键是字符串类型的;为了引用它们,我们需要在模块名周围放上引号(比如"humansize")。但是在使用替换域的时候,我们在省略了字典的键名周围的引号(比如humansize)。在此,我们引用PEP 3101:字符串格式化高级用法,解析键名的规则非常简单。如果名字以数字开头,则它被当作数字使用,其他情况则被认为是字符串。
-
sys.modules["humansize"].SUFFIXES是在humansize模块的开头定义的一个字典对象。{0.modules[humansize].SUFFIXES}即指向该字典。
-
sys.modules["humansize"].SUFFIXES[1000]是一个SI(国际单位制)后缀列表:["KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"]。所以替换域{0.modules[humansize].SUFFIXES[1000]}指向该列表。
-
sys.modules["humansize"].SUFFIXES[1000][0]即SI后缀列表的第一个元素:"KB"。因此,整个替换域{0.modules[humansize].SUFFIXES[1000][0]}最后都被两个字符KB替换。
格式说明符
但是,还有一些问题我们没有讲到!再来看一看humansize.py中那一行奇怪的代码:
if size < multiple: return "{0:.1f} {1}".format(size, suffix)
{1}会被传递给format()方法的第二个参数替换,即suffix。但是{0:.1f}是什么意思呢?它其实包含了两方面的内容:{0}你已经能理解,:.1f则不一定了。第二部分(包括冒号及其后边的部分)即格式说明符(format specifier),它进一步定义了被替换的变量应该如何被格式化。
格式说明符的允许你使用各种各种实用的方法来修饰被替换的文本,就像C语言中的printf()函数一样。我们可以添加使用零填充(zero-padding),衬距(space-padding),对齐字符串(align strings),控制10进制数输出精度,甚至将数字转换成16进制数输出。
在替换域中,冒号(:)标示格式说明符的开始。.1的意思是四舍五入到保留一们小数点。f的意思是定点数(与指数标记法或者其他10进制数表示方法相对应)。因此,如果给定size为698.24,suffix为"GB",那么格式化后的字符串将是"698.2 GB",因为698.24被四舍五入到一位小数表示,然后后缀"GB"再被追加到这个串最后。
>>> "{0:.1f} {1}".format(698.24, "GB")
"698.2 GB"
想了解格式说明符的复杂细节,请参阅Python官方文档关于格式化规范的迷你语言。
python判断字符串是否由纯数字组成
import re
def IsFloatStr(s):
'''
浮点数判断
'''
try:
float(s)
# s.isdigit() # 这个是错的,不能判断
# 正则表达式实现
# return True if re.match(r'[-+]*\d+?\.{0,1}\d*$', s) else False
return True
except:
return Falsedef IsIntStr(s):
'''
整数判断
'''
try:
int(s)
# s.isdigit()#这个是错的,不能判断
# return True if re.match(r'[-+]*\d+$', s) else False
return True
except:
return False
for s in ['123', '-123', '+123', '-12.3', '-1.2.3', '123hello']:
print('s is a num str' if IsFloatStr(s) else 's is not a num str')
print('s is a num str' if IsIntStr(s) else 's is not a num str')
python删除字符串中空白字符:换行、空格、制表符
print(' '.join("Please \n don't \t hurt me.".split()))
输出:
Please don't hurt me.
Python字符串逐字符或逐词反转方法
-
x='abcd'
-
In [66]: x[::-1]
-
Out[66]: 'dcba'
-
y=reversed(x)
-
In [57]: y
-
Out[57]: <reversed object at 0x058302F0>
-
In [58]: ''.join(y)
-
Out[58]: 'dcba'
1. 创建一个列表,将列表反转,用join方法合并
s='Today is really a good day'
rev=' '.join(s.split()[::-1])
2. 可以不改变原先的空格,采用正则式来做-
revwords=' '.join(reversed(s.split()))
-
revwords=''.join(reversed(re.split(r'(\s+)',s)))
其他常用字符串技巧
除了格式化,关于字符串还有许多其他实用的使用技巧。
>>> s = """Finished files are the re-... sult of years of scientif-... ic study combined with the... experience of years.""">>> s.splitlines()["Finished files are the re-", "sult of years of scientif-", "ic study combined with the", "experience of years."]>>> print(s.lower())finished files are the re-sult of years of scientif-ic study combined with theexperience of years.>>> s.lower().count("f")6
-
我们可以在Python的交互式shell里输入多行(multiline)字符串。一旦我们以三个引号标记多行字符串的开始,按ENTER键,Python shell会提示你继续这个字符串的输入。连续输入三个结束引号以终止该字符串的输入,再敲ENTER键则会执行该条命令(在当前例子中,把这个字符串赋给变量s)。
-
splitlines()
方法以多行字符串作为输入,返回一个由字符串组成的列表,列表的元素即原来的单行字符串。请注意,每行行末的回车符没有被包括进去。 -
lower()
方法把整个字符串转换成小写的。(类似地,upper()
方法执行大写化转换操作。) -
count()
方法对串中的指定的子串进行计数。是的,在那一句中确实出现了6个字母f。
还有一种经常会遇到的情况。比如有如下形式的键-值对列表 key1=value1&key2=value2
,我们需要将其分离然后产生一个这样形式的字典{key1: value1, key2: value2}
。
>>> query = "user=pilgrim&database=master&password=PapayaWhip">>> a_list = query.split("&")>>> a_list["user=pilgrim", "database=master", "password=PapayaWhip"]>>> a_list_of_lists = [v.split("=", 1) for v in a_list]>>> a_list_of_lists[["user", "pilgrim"], ["database", "master"], ["password", "PapayaWhip"]]>>> a_dict = dict(a_list_of_lists)>>> a_dict{"password": "PapayaWhip", "user": "pilgrim", "database": "master"}
-
split()
方法使用一个参数,即指定的分隔符,然后根据这个分隔符将串分离成一个字符串列表。此处,分隔符即字符&
,它还可以是其他的内容。 -
现在我们有了一个字符串列表,其中的每个串由三部分组成:键,等号和值。我们可以使用列表解析来遍历整个列表,然后利用第一个等号标记将每个字符串再分离成两个子串。(理论上,值也可以包含等号标记,如果执行
"key=value=foo".split("=")
,那么我们会得到一个三元素列表["key", "value", "foo"]
。) -
最后,通过调用
dict()
函数Python会把那个包含列表的列表(list-of-lists)转换成字典对象。
上一个例子跟解析URL的请求参数(query parameters)很相似,但是真实的URL解析实际上比这个复杂得多。如果需要处理URL请求参数,我们最好使用
urllib.parse.parse_qs()
函数,它可以处理一些不常见的边缘情况。
python 2.x和3.x中的字符串编码区别
String vs. Bytes
python string对象和bytes对象的区别
字节即字节;字符是一种抽象。一个不可变(immutable)的Unicode编码的字符序列叫做string。
bytes对象:一串由0到255之间的数字组成的序列。
by = b"abcde"
len(by)
5
by += b"ÿ"
by
b"abcdeÿ"
by[0]
97
by[0] = 102
<samp class="traceback">Traceback (most recent call last): File "<stdin>", line 1, in <module>TypeError: "bytes" object does not support item assignment
-
使用byte字面值语法b""来定义bytes对象。byte字面值里的每个字节可以是ASCII字符或者是从到ÿ编码了的16进制数。bytes对象的类型是bytes。
-
使用+操作符可以连接bytes对象。操作的结果是一个新的bytes对象。连接5个字节的和1个字节的bytes对象会返回一个6字节的bytes对象。
-
如列表和字符串,可以使用下标记号来获取bytes对象中的单个字节。对字符串做这种操作获得的元素仍为字符串,而对bytes对象做这种操作的返回值则为整数。确切地说,是0–255之间的整数。
-
bytes对象是不可变的;我们不可以给单个字节赋上新值。如果需要改变某个字节,可以组合使用字符串的切片和连接操作(效果跟字符串是一样的),或者我们也可以将bytes对象转换为bytearray对象。
- by = b"abcde"
barr = bytearray(by)
barr
bytearray(b"abcde")
barr[0] = 102
barr
bytearray(b"fbcde")
-
所有对bytes对象的操作也可以用在bytearray对象上。
-
有一点不同的就是,我们可以使用下标标记给bytearray对象的某个字节赋值。并且,这个值必须是0–255之间的一个整数。
不能混用bytes和strings
by = b"d"
s = "abcde"
by + s
Traceback (most recent call last): File "<stdin>", line 1, in <module>TypeError: can"t concat bytes to str
s.count(by)
Traceback (most recent call last): File "<stdin>", line 1, in <module>TypeError: Can"t convert "bytes" object to str implicitly
s.count(by.decode("ascii"))
1
-
不能连接bytes对象和字符串。他们两种不同的数据类型。
-
也不允许针对字符串中bytes对象的出现次数进行计数,因为串里面根本没有bytes。字符串是一系列的字符序列。也许你是想要先把这些字节序列通过某种编码方式进行解码获得字符串,需要显式地指明它。Python 3不会隐含地将bytes转换成字符串,或者进行相反的操作。
print('pro' == b'pro')
flase
字符串与字节数组之间的联系
bytes对象有一个decode()方法,它使用某种字符编码作为参数,然后依照这种编码方式将bytes对象转换为字符串,对应地,字符串有一个encode()方法,它也使用某种字符编码作为参数,然后依照它将串转换为bytes对象。
在上一个例子中,解码的过程相对直观一些 -- 使用ASCII编码将一个字节序列转换为字符串。同样的过程对其他的编码方式依然有效 -- 传统的(非Unicode)编码方式也可以,只要它们能够编码串中的所有字符。
a_string = "深入 Python"
len(a_string)
9
by = a_string.encode("utf-8")
by
b"深入 Python"
len(by)
13
by = a_string.encode("gb18030")
by
b"ÉîÈë Python"
len(by)
11
by = a_string.encode("big5")
by
b"²`¤J Python"
len(by)
11
roundtrip = by.decode("big5")
roundtrip
"深入 Python"
a_string == roundtrip
True
Note:roundtrip是一个字符串,共有9个字符。它是通过对by使用Big5解码算法得到的一个字符序列。并且,从执行结果可以看出,roundtrip与a_string是完全一样的。