python学习04-序列

序列包括:字符串,列表,和元组类型。
序列类型有着相同的访问模式:它的每一个元素可以通过指定一个偏移量的方式得到。而多个元素可以通过切片操作的方式一次得到。
序列类型操作符
成员关系操作符 (in, not in),该操作符的语法如下:
obj [not] in sequence
序列类型操作符
seq[ind] 获得下标为ind的元素
seq[ind1:ind2] 获得下标从ind1至ind2之间的元素
seq * expr seq序列重复exper次
seq1 + seq2 连接学列seq1 和seq2
obj in seq 判断obj元素是否在seq序列中
obj not in seq 判断obj元素是否不在seq序列中
序列其中一个切片操作是扩展切片操作,它多出来的第三个索引值被用做步长参数。
例子:
S= ‘abcdefgh’
s[::-1] #可以视作翻转操作
‘hgfedcba’
s[::2] #隔一个取一个的操作
‘aceg’
内建函数:
类型转换:
list(iter) 把可迭代对象转换成列表
str(obj) 把obj对象转换成字符串
unicode(obj) 把obj对象转换成Unicode字符串
basestring() 抽象工厂函数,其作用仅仅是为str和unicode函数提供父类,不能被实例化也不能被调用
tuple(iter) 把可迭代对象转换成元组
序列类型可用的内建函数
enumerate(iter) 接受一个可迭代对象作为参数,返回一个enumerate对象,该对象生成由iter每个元素的index值和item值组成的元组
len(seq) 返回seq的长度
max(iter, key=None) or max(arg0, arg1…, key=None) 返回iter或arg0,arg1….中的最大值,如果指定了key,key必须是一个可以传给sort()方法的可回调函数。
min与max语法相同
reversed(seq) 接受一个序列作为参数,返回一个以逆序访问的迭代器
sort(iter, func=None, key=None, reversed=False) 接受一个可迭代对象最为参数,返回一个有序的列表
sun(seq, init=0) 返回seq和可选参数init的和
注意,len(),reversed()和 sum()函数只能接受序列类型对象作为参数,而剩下的则还可以接受可迭代对象做为参数,另外,max()和 min()函数也可以接受一个参数列表.
字符串
Python 实际上有 3 类字符串.通常意义的字符串(str)和 Unicode 字符串(unicode)实际上都是抽象类 basestring 的子类.这个basestring 是不能实例化的。
通过赋一个空字符串或者使用 del 语句来清空或者删除一个字符串
在做比较操作的时候,字符串是按照 ASCII 值的大小来比较的。
成员操作符(in ,not in)
成员操作符用于判断一个字符或者一个子串(中的字符)是否出现在另一个字符串中。
只适用于字符串的操作符
格式化操作符( % )
字符串模板
Template 对象有两个方法,substitute()和 safe_substitute().前者更为严谨,在 key 缺少的情况下它会报一个 KeyError 的异常出来,而后者在缺少 key 时,直接原封不动的把字符串显示出来。
原始字符串操作符( r/R )
关于原始字符串的目的,在 Python1.5 里面已经有说明,是为了对付那些在字符串中出现的特殊字符。在原始字符串里,所有的字符都是直接按照字面的意思来使用,没有转义特殊或不能打印的字符。
Unicode 字符串操作符( u/U )
Unocide 字符串操作符,大写的(U)和小写的(u).它用来把标准字符串或者是包含 Unicode 字符的字符串转换成完全地 Unicode 字符串对象。注意:Unicode 操作符必须出现在原始字符串操作符前面.
内建函数
标准类型函数
enumerate()
///s = ‘foobar’
///for i, t in enumerate(s):
print i, t
zip()
///s, t = ‘foa’, ‘obr’
///zip(s, t)
str() and unicode()
str()和 unicode()函数都是工厂函数,就是说产生所对应的类型的对象.它们接受一个任意类型的对象,然后创建该对象的可打印的或者 Unicode 的字符串表示.
chr(), unichr(), and ord()
chr()函数用一个范围在 range(256)内的(就是 0 到 255)整数做参数,返回一个对应的字符.unichr()跟它一样,只不过返回的是 Unicode 字符ord()函数是 chr()函数(对于 8 位的 ASCII 字符串)或 unichr()函数(对于 Unicode 对象)的配对函数,它以一个字符(长度为 1 的字符串)作为参数,返回对应的 ASCII 数值,或者 Unicode数值.
三引号
Python 的三引号就是为了解决这个问题的,它允许一个字符串跨多行,字符串中可以包含换行符、制表符以及其他特殊字符.
codec 是 COder/DECoder 的首字母组合.它定义了文本跟二进制值的转换方式,跟 ASCII 那种用一个字节把字符转换成数字的方式不同,Unicode 用的是多字节.这导致了 Unicode 支持多种 不 同 的 编 码 方 式 .
注意:
程序中出现字符串时一定要加个前缀 u.
不要用 str()函数,用 unicode()代替.
不要用过时的 string 模块 – 如果传给它的是非 ASCII 字符,它会把一切搞砸。
不到必须时不要在你的程序里面编解码 Unicod 字符.只在你要写入文件或数据库或者网络时,才调用 encode()函数;相应地,只在你需要把数据读回来的时候才调用 decode()函数.
re
正则表达式(RE)提供了高级的字符串模式匹配方案.通过描述这些模式的语法,你可以像使用“过滤器”一样高效地查找传进来的文本。这些过滤器允许你基于自定义的模式字符串抽取匹配模式、执行查找-替换或分割字符串.
列表
列表则是能保留任意数目的 Python 对象的灵活的容器。列表
可以包含不同类型的对象,而且要比 C 或者 Python 自己的数组类型(包含在 array 扩展包中)都要灵活.因为数组类型所有的元素只能是一种类型.列表可以执行 pop,empt,sort,reverse 等操作.列表也可以添加或者减少元素.还可以跟其他的列表结合或者把一个列表分成几个.可以对单独一个元素或者多个元素执行 insert,update,或者 remove 操作.
创建一个列表就像给一个变量赋值一样的简单.你手工写一个列表(空的或者有值的都行)然后赋给一个变量,列表是由方括号([])来定义的,当然,你也可以用工厂方法来创建它.
如何更新列表
你可以通过在等号的左边指定一个索引或者索引范围的方式来更新一个或几个元素,你也可以用 append()方法来追加元素到列表中去.
如何删除列表中的元素或者列表(本身)
要删除列表中的元素,如果你确切的知道要删除元素的素引可以用 del 语句,否则可以用remove()方法.
列表类型的元素可以是另一个序列类型,这就意味着你在列表的元素上也可以使用所有的序列操作符或者在其之上执行序列类型内建的各种操作.
连接接操作符( + )
连接操作符允许我们把多个列表对象合并在一起.注意,列表类型的连接操作也只能在同类型之间进行,换句话说,你不能把两个不同类型的对象连接在一起,即便他们都是序列类型也不行.使用 extend()方法比连接操作的一个优点是它实际上是把新列表添加到了原有的列表里面,而不是像连接操作那样新建一个列表。list.extend()方法也被用来做复合赋值运算,也就是 Python2.0 中添加的替换连接操作(+=).
连接操作符并不能实现向列表中添加新元素的操作.连接操作符的左右两边使用了不同类型的值,列表类型 + 字符串类型这样的操作是非法的.使用内建函数 append()添加新元素。
标准类型函数
cmp()
1.对两个列表的元素进行比较.
2.果比较的元素是同类型的,则比较其值,返回结果.
3.如果两个元素不是同一种类型,则检查它们是否是数字.
a. 如果是数字,执行必要的数字强制类型转换,然后比较.
b. 如果有一方的元素是数字,则另一方的元素”大”(数字是”最小的”)
c. 否则,通过类型名字的字母顺序进行比较.
4.果有一个列表首先到达末尾,则另一个长一点的列表”大”.
5.如果我们用尽了两个列表的元素而且所有元素都是相等的,那么结果就是个平局,就是说返回一个 0.
list() and tuple()
list()函数和 tuple()函数接受可迭代对象(比如另一个序列)作为参数,并通过浅拷贝数据来创建一个新的列表或者元组.虽然字符串也是序列类型的,但是它们并不是经常用于 list()和tuple(). 更多的情况下,它们用于在两种类型之间进行转换,比如你需要把一个已有的元组转成列表类型的(然后你就可以修改它的元素了),或者相反.
列表类型的内建函数
它们都不适应于元组.
list.append(obj) 向列表中添加一个对象 obj
list.count(obj) 返回一个对象 obj 在列表中出现的次数
list.extend(seq) 把序列 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) 删除并返回指定位置的对象,默认是最后一个对象
list.remove(obj) 从列表中删除对象 obj
list.reverse() 原地翻转列表
list.sort(func=None,key=None,reverse=False) 以指定的方式排序列表中的成员,如果 func 和 key 参数指定,则按照指定的方式比较各个元素,如果 reverse 标志被置为True,则列表以反序排列.
那些可以改变对象值的可变对象的方法是没有返回值的!在使用可变对象的方法如 sort(),extend()和 reverse()的时候要注意,这些操作会在列表中原地执行操作,也就是说现有的列表内容会被改变,但是没有返回值!是的,与之相反,字符串方法确实有返回值.
字符串是不可变的 – 不可变对象的方法是不能改变它们的值的,所以它们必须返回一个新的对象.
元组
功能上,元组和列表相比有一个很重要的区别,元组是一种不可变类型
创建一个元组并给他赋值实际上跟创建一个列表并给它赋值完全一样,除了一点,只有一个元素的元组需要在元组分割符里面加一个逗号(,)用以防止跟普通的分组操作符混淆.不要忘了这是一个工厂方法!
元组的对象和序列类型操作符还有内建函数跟列表的完全一样.你仍然可以对元组进行切片操作,合并操作,以及多次拷贝一个元组,还可以检查一个对象是否属于一个元组,进行元组之间的比较等.
像列表一样 元组也没有它自己专用的运算符和内建函数.列表方法都跟列表对象的可变性有关,比如说排序,替换,添加等等,因为元组是不可变的,所以这些操作对元组来说就是多余的,这些方法没有被实现.
所有的多对象的,逗号分隔的,没有明确用符号定义的,比如说像用方括号表示列表和用圆括号表示元组一样,等等这些集合默认的类型都是元组。
所有函数返回的多对象(不包括有符号封装的)都是元组类型。注意,有符号封装的多对象集合其实是返回的一个单一的容器对象。
创建单元素元组是在第一个元素后面添一个逗号(,)来表明这是一个元组而不是在做分组操作。
不可变对象的值是不可改变的。这就意味着它们通过 hash 算法得到的值总是一个值。这是作为字典键值的一个必备条件。在下一章节里面我们会讨论到,键值必须是可哈希的对象,元组变量符合这个标准,而列表变量就不行。
与序列类型相关的模块
数组 一种受限制的可变序列类型,要求所有的元素必须都是相同的类型。
copy 提供浅拷贝和深拷贝的能力
operater 包含函数调用形式的序列操作符,比如 operator.concat(m,n)就相当于连接操作(m+n)。
re Perl 风格的正则表达式查找(和匹配)
StringIO/cStringIO 把长字符串作为文件来操作,比如 read(),seek()函数等,C 版的更快一些,但是它不能被继承.
Textwrap 用作包裹/填充文本的函数,也有一个类
types 包含 Python 支持的所有类型
collections 高性能容器数据类型

拷贝 Python 对象 浅拷贝和深拷贝
对一个对象进行浅拷贝其实是新创建了一个类型跟原对象一样,其内容是原来对象元素的引用,换句话说,这个拷贝的对象本身是新的,但是它的内容不是.序列类型对象的浅拷贝是默认类型拷贝,并可以以下几种方式实施:(1)完全切片操作[:],(2)利用工厂函数,比如 list(),dict()等,(3)使用 copy 模块的 copy 函数.
person = [‘name’, [‘savings’, 100.00]]
hubby = person[:] # slice copy
///wifey = list(person) # fac func copy
hubby[0] = ‘joe’
wifey[0] = ‘jane’
/// hubby[1][1] = 50.00
hubby, wifey
([‘joe’, [‘savings’, 50.0]], [‘jane’, [‘savings’, 50.0]])

上例中当修改hubby的账户余额时wifey的值也改变了。可是wifey改名字的时候hubby的名字没有受到影响。这是因为在这两个列表的两个对象中,第一个对象是不可变的(是个字符串类型),而第二个是可变的(一个列表).正因为如此,当进行浅拷贝时,字符串被显式的拷贝,并新创建了一个字符串对象,而列表元素只是把它的引用复制了一下,并不是它的成员.所以改变名字没有任何问题,但是更改他们银行账号的任何信息都会引发问题.

要得到一个完全拷贝或者说深拷贝–创建一个新的容器对象,包含原有对象元素(引用)全新拷贝的引用–需要 copy.deepcopy()函数.我们使用深拷贝来重写整个例子.
/// person = [‘name’, [‘savings’, 100.00]]
/// hubby = person
/// import copy
/// wifey = copy.deepcopy(person)
/// hubby[0] = ‘joe’
/// wifey[0] = ‘jane’
/// hubby[1][1] = 50.00
/// hubby, wifey
([‘joe’, [‘savings’, 50.0]], [‘jane’, [‘savings’, 100.0]])

第一,非容器类型(比如数字,字符串和其他”原子”类型的对象,像代码,类型和 xrange 对象等)没有被拷贝一说,浅拷贝是用完全切片操作来完成的.第二,如果元组变量只包含原子类型对象,对它的深拷贝将不会进行.如果我们把账户信息改成元组类型,那么即便按我们的要求使用深拷贝操作也只能得到一个浅拷贝。我们刚才描述的浅拷贝和深拷贝操作都可以在 copy 模块中找到.其实 copy 模块中只有两个函数可用:copy()进行浅拷贝操作,而 deepcopy()进行深拷贝操作.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值