python第二版6章笔记--序列: 字符串、列表和元 组

6.1 序列

成员有序排列的,并且可以通过下标偏移量访问到它的一个或者几个成员, 这类 Python 类型统称为序列, 包括下面这些: 字符串(普通字符串和 unicode 字符串),列表,和元组类型。
序列类型有着相同的访问模式:它的每一个元素可以通过指定一个偏移量的方式得到。而多个元素可以通过切片操作的方式一次得到。
成员关系操作符 (in, not in) obj [not] in sequenc
连接操作符( + ),允许我们把一个序列和另一个相同类型的序列做连接。语法如下:sequence1 + sequence2。对字符串来说,这个操作不如把所有的子字符串放到一个列表或可迭代对象中,然后调用一个 join方法来把所有的内容连接在一起节约内存;类似地,对列表来说,我们推荐读者用列表类型的extend()方法来把两个或者多个列表对象合并。
切片操作符 ( [], [:], [::] ),序列类型是其元素被顺序放置的一种数据结构类型,这种方式允许通过指定下标的方式来获得某一个数据元素, 或者通过指定下标范围来获得一组序列的元素.这种访问序列的方式叫做切片。切片索引的语法要比简单的单一元素索引灵活的多。开始和结束素引值可以超过字符串的长度。sequence[starting_index:ending_index]--------------- 对任何范围[start:end],我们可以访问到包括 start 在内到 end(不包括 end)的所有字符。

序列类型转换工厂函数
函数 含义
list(iter) 把可迭代对象转换为列表
str(obj) 把 obj 对象转换成字符串(对象的字符串表示法)
unicode(obj) 把对象转换成 Unicode 字符串(使用默认编码)
basestring() 抽象工厂函数,其作用仅仅是为 str 和 unicode 函数提供父类,所以不能被实例化,也不能被调用(详见第 6.2 节)
tuple(iter) 把一个可迭代对象转换成一个元组对象

转换:一旦一个 Python 的对象被建立,我们就不能更改其身份或类型了.如果你把一个列表对象传给 list()函数,便会创建这个对象的一个浅拷贝,然后将其插入新的列表中。

函数名 功能
enumerate(iter) a 接受一个可迭代对象作为参数,返回一个 enumerate 对象(同时也是一个迭代器),该对象生成由 iter 每个元素的 index 值和 item 值组成的元组(PEP 279)
len(seq) 返回 seq 的长度
max(iter,key=None) or max(arg0,arg1...,key=None) b 返回iter或(arg0,arg1,...)中的最大值, 如果指定了key, 这个 key 必须是一个可以传给 sort()方法的,用于比较的回调函数.
min(iter, key=None) or min(arg0, arg1.... key=None) b 返回 iter 里面的最小值;或者返回(arg0,arg2,...)里面Edit By Vheavens的最小值;如果指定了 key,这个 key 必须是一个可以传给sort()方法的,用于比较的回调函数.
reversed(seq) c 接受一个序列作为参数,返回一个以逆序访问的迭代器(PEP 322)
sorted(iter,func=None,key=None,reverse=False) c 接受一个可迭代对象作为参数,返回一个有序的列表;可选参数func,key 和 reverse 的含义跟 list.sort()内建函数的参数含义一样.
sum(seq, init=0) a 返 回 seq 和 可 选 参 数 init 的 总 和 , 其 效 果 等 同 于 reduce(operator.add,seq,init)
zip([it0, it1,... itN]) d 返回一个列表,其第一个元素是 it0,it1,...这些元素的第一个元素组成的一个元组,第二个...,类推.
s, t = 'foavv', 'obr' >>> zip(s, t) 返回 [('f', 'o'), ('o', 'b'), ('a', 'r')]

6.2 字符串

字符串类型是 Python 里面最常见的类型.我们可以简单地通过在引号间包含字符的方式创建它.
Python 里面单引号和双引号的作用是相同的,这一点 Python 不同于其他类 Shell 的脚本语言,在这些脚本语言中,通常转义字符仅仅在双引号字符串中起作用,在单一号括起的字符串中不起作用。Python 用"原始字符串"操作符来创建直接量字符串,所以再做区分就没什么意义了。其他的语言,比如 C 语言里面用单引号来标示字符,双引号标示字符串,而在 Python里面没有字符这个类型.这可能是双引号和单引号在 Python 里面被视作一样的的另一个原因.
几乎所有的 Python 应用程序都会某种方式用到字符串类型.字符串是一种直接量或者说是一种标量,这意味着Python解释器在处理字符串时是把它作为单一值并且不会包含其他Python类型的。字符串是不可变类型,就是说改变一个字符串的元素需要新建一个新的字符串.字符串是由独立的字符组成的,并且这些字符可以通过切片操作顺序地访问。
Python 风格的字符串格式化操作符。只适用于字符串类型,非常类似于 C 语言里面的printf()函数的字符串格式化,甚至所用的符号都一样, 都用百分号(%), 并且支持所有 printf()式的格式化操作.
ord()函数是 chr()函数(对于 8 位的 ASCII 字符串)或 unichr()函数(对于 Unicode 对象)的配对函数,它以一个字符(长度为 1 的字符串)作为参数,返回对应的 ASCII 数值.

string.lower() 转换 string 中所有大写字符为小写.
string.swapcase() 翻转 string 中的大小写
string.upper() 转换 string 中的小写字母为大写
string.capitalize() 把字符串的第一个字符大写
string.partition(str) e 有点像 find()和 split()的结合体,从 str 出现的第一个位置起,把 字 符 串 string 分 成 一 个 3 元 素 的 元 组(string_pre_str,str,string_post_str),如果 string 中不包含str 则 string_pre_str == string.
string.replace(str1, str2,num=string.count(str1))把 string 中的 str1 替换成 str2,如果 num 指定,则替换不超过 num 次.
string.split(str="", num=string.count(str)) 以 str 为分隔符切片 string,如果 num有指定值,则仅分隔 num 个子字符串
str = "Chris_iven+Chris_jack+Chrislusy" print str.split("+") print str.split("")

虽然你可以用单引号或者双引号来定义字符串,但是如果你需要包含诸如换行符这样的特殊字符时,单引号或者双引号就不是那么方便了。Python 的三引号就是为了解决这个问题的,它允许一个字符串跨多行,字符串中可以包含换行符、制表符以及其他特殊字符.三引号的语法是一对连续的单引号或者双引号(通常都是成对的用),常见于html和mysql中。
字符串是一种不可变数据类型,就是说它的值是不能被改变或修改的。这就意味着如果你想修改一个字符串,或者截取一个子串,或者在字符串的末尾连接另一个字符串等等,你必须新建一个字符串。Python 分别为"abc"和"def"分配了空间,当进行连接操作时,Python 自动为新的字符串"abcdef"分配了空间。
s = 'abc' >>> s = s + 'def' >>> s 'abcdef' 事实是在"s+'def""这个操作进行的时候,新建了一个新字符串,然后这个新的对象被赋给了 s,原来的字符串'abc'被析构掉了。
Unicode 通过使用一个或多个字节来表示一个字符的方法突破了 ASCII 的限制, Unicode 可以表示超过 90,000 个字符.在 Unicode 之前,用的都是ASCII,ASCII 码非常简单,每个英文字符都是以七位二进制数的方式存贮在计算机内,其范围是 32 到 126.当用户在文件中键入一个大写字符 A 时,计算机会把 A 的 ASCII 码值 65。写入磁盘,然后当计算机读取该文件时,它会首先把 65 转化成字符 A 然后显示到屏幕上.但是ASCII字符只能表示95个可打印字符.后来的软件厂商把ASCII 码扩展到了 8 位,这样一来它就可以多标识 128 个字符,可是 223 个字符对需要成千上万的字符的非欧洲语系的语言来说仍然太少。
s=u'aaaa' se=s.encode('utf-8') >>> se 返回 'aaaa'
sd=se.decode('utf-8') >>> sd 返回 u'aaaa'
decode()和 encode()内建函数接受一个字符串做参数返回该字符串对应的解码后/编码后的字符串。

codec 是 COder/DECoder 的首字母组合.它定义了文本跟二进制值的转换方式,跟 ASCII 那种用一个字节把字符转换成数字的方式不同,Unicode 用的是多字节.这导致了 Unicode 支持多种不同的编码方式.比如说 codec 支持的四种耳熟能详的编码方式是 :ASCII,ISO8859-1/Latin-1,UTF-8 和 UTF-16.其中最著名的是UTF-8编码, 它也用一个字节来编码ASCII字符。
程序中出现字符串时一定要加个前缀 u.
? 不要用 str()函数,用 unicode()代替.
? 不要用过时的 string 模块 -- 如果传给它的是非 ASCII 字符,它会把一切搞砸。
? 不到必须时不要在你的程序里面编解码 Unicod 字符.只在你要写入文件或数据库或者网络时, 才调用 encode()函数;相应地, 只在你需要把数据读回来的时候才调用 decode()函数.
?在你系统里面的第三方模块(包括你的应用要面对的平台\系统)需要用相同的 Unicode 编码,否则,可能你就不能正确的读写数据.

除了 pickle 模块! pickle 模块只支持 ASCII 字符串。如果你把一个 Unicode 字符串交给 pickle 模块来 unpickle,它会报异常.你必须先把你的字符串转换成 ASCII 字符串才可以.所以最好是避免基于文本的 pickle 操作.
比如说 MySQLdb,它并不是默认就支持 Unicode 模式,你必须在 connect()方法里面用一个特殊的关键字 use_unicode来确保你得到的查询结果是 Unicode 字符串.
总结: 使应用程序完全支持 Unicode,兼容其他的语言本身就是一个工程.

模块 描述
string 字符串操作相关函数和工具,比如 Template 类.
re 正则表达式:强大的字符串模式匹配模块
struct 字符串和二进制之间的转换
c/StringIO 字符串缓冲对象,操作方法类似于 file 对象.
crypt 进行单方面加密
difflib a 找出序列间的不同
md5 d RSA 的 MD5 信息摘要鉴权
rotor 提供多平台的加解密服务

6.3 列表

像字符串类型一样,列表类型也是序列式的数据类型,可以通过下标或者切片操作来访问某一个或者某一块连续的元素.然而,相同的方面也就这些,字符串只能由字符组成,而且是不可变的(不能单独改变它的某个值),而列表则是能保留任意数目的 Python 对象的灵活的容器。
列表可以包含不同类型的对象,而且要比 C 或者 Python 自己的数组类型(包含在 array 扩展包中)都要灵活.因为数组类型所有的元素只能是一种类型.列表可以执行 pop,empt,sort,reverse 等操作.列表也可以添加或者减少元素.还可以跟其他的列表结合或者把一个列表分成几个.可以对单独一个元素或者多个元素执行 insert,update,或者 remove 操作.
元组类型在很多操作上都跟列表一样,许多用在列表上的例子在元组上照样能跑,我们有一节内容专门讲解元组类型.它们的主要不同在于元组是不可变的,或者说是只读的,所以那些用于更新列表的操作,比如用切片操作来更新一部分元素的操作,就不能用于元组类型.
如何创建列表类型数据并给它赋值 列表是由方括号([])来定义的。 aList = [123, 'abc', 4.56, ['inner', 'list'], 7-9j]
如何访问列表中的值 aList[1:4] 返回 ['abc', 4.56, ['inner', 'list']] >>> aList[3][1] 返回 'list'
如何更新列表 等号的左边指定一个索引或者索引范围的方式来更新一个或几个元素,你也可以用 append()方法来追加元素到列表中去
aList[2] = 'float replacer' aList.append("hi, i'm new here") aList.append(123) --只能一个元素
如何删除列表中的元素或者列表(本身) 要删除列表中的元素,如果你确切的知道要删除元素的素引可以用 del 语句,否则可以用remove()方法.
del aList[1] aList.remove(123) aList.remove(aList[2]) aList.pop(1) 返回指定对象删除的元素
成员关系操作( in ,not in) 连接接操作符( + ) 重复操作符( * )
sorted() and reversed() cmp() len() max() and min() enumerate() and zip() sum()
list() and tuple()函数接受可迭代对象(比如另一个序列)作为参数,并通过浅拷贝数据来创建一个新的列表或者元组
list.append(obj) 向列表中添加一个对象 obj
list.count(obj) 返回一个对象 obj 在列表中出现的次数
list.extend(seq) a 把序列 seq 的内容添加到列表中
list.index(obj, i=0,j=len(list)) 返回 list[k] == obj 的 k 值,并且 k 的范围在 i<=k<j;否则引发 ValueError 异常.
list.insert(index, obj) 在索引量为 index 的位置插入对象 obj.
list.pop(index=-1) a 删除并返回指定位置的对象,默认是最后一个对象
list.remove(obj) 从列表中删除对象 obj
list.reverse() 原地翻转列表
list.sort(func=None,key=None,reverse=False) b 以指定的方式排序列表中的成员,如果 func 和 key 参数指定,则按照指定的方式比较各个元素,如果 reverse 标志被置为True,则列表以反序排列.**

堆栈是一个后进先出(LIFO)的数据结构
队列是一种先进先出(FIFO)的数据类型

6.4 元祖

元组和列表看起来不同的一点是元组用的是圆括号而列表用的是方括号。
如何创建一个元组并给它赋值 如何访问元组中的值 如何更新元组
如何移除一个元组的元素以及元组本身 删除一个单独的元组元素是不可能的,当然,把不需要的元素丢弃后, 重新组成一个元组是没有问题的.

比如说排序,替换,添加等等,因为元组是不可变的,所以这些操作对元组来说就是多余的,这些方法没有被实现.
不可变并不是坏事,比如我们把数据传给一个不了解的 API 时,可以确保我们的数据不会被修改。同样地,如果我们操作从一个函数返回的元组,可以通过内建 list()函数把它转换成一个列表.
list()和 tuple()函数允许你用一个列表来创建一个元组,反之亦然.如果你有一个元组变量,但你需要一个列表变量因为你要更新一下它的对象,这时 list()函数就是你最好的帮手.如果你有一个列表变量,并且想把它传递给一个函数,或许一个 API,而你又不想让任何人弄乱你的数据,这时 tuple()函数就非常有用。

比如,假设你想创建一对小夫妻的通用档案,名为 person.然后你分别为他俩拷贝一份。
python第二版6章笔记--序列: 字符串、列表和元 组
你的下一个问题可能是:当妻子的名字被赋值,为什么丈夫的名字没有受到影响?难道它们的名字现在不应该都是'jane'了吗?为什么名字没有变成一样的呢?怎么会是这样呢?这是因为在这两个列表的两个对象中,第一个对象是不可变的(是个字符串类型),而第二个是可变的(一个列表).正因为如此,当进行浅拷贝时,字符串被显式的拷贝,并新创建了一个字符串对象,而列表元素只是把它的引用复制了一下,并不是它的成员.所以改变名字没有任何问题,但是更改他们银行账号的任何信息都会引发问题.现在,让我们分别看一下每个列表的元素的对象 ID 值,注意,银行账号对象是同一个对象,这也是为什么对一个对象进行修改会影响到另一个的原因.注意在我们改变他们的名字后,新的名字字符串是如何替换原有'名字'字符串的.
假设我们要给这对夫妻创建一个联合账户,那这是一个非常棒的方案,但是,如果需要的是两个分离账户,就需要作些改动了.要得到一个完全拷贝或者说深拷贝--创建一个新的容器对象,包含原有对象元素(引用)全新拷贝的引用--需要 copy.deepcopy()函数.我们使用深拷贝来重写整个例子.
python第二版6章笔记--序列: 字符串、列表和元 组
python第二版6章笔记--序列: 字符串、列表和元 组
浅拷贝和深拷贝操作都可以在 copy 模块中找到.其实 copy 模块中只有两个函数可用:copy()进行浅拷贝操作,而 deepcopy()进行深拷贝操作

https://blog.51cto.com/benshitong/2058446 python第二版7章笔记--映射和集合类型

转载于:https://blog.51cto.com/benshitong/2058344