python核心编程&序列

来源:互联网 发布:2001年全明星赛数据 编辑:程序博客网 时间:2024/06/07 01:54

在之前的篇章中,也曾提到字符串、列表、元组均属于序列。那么,今天就来说说序列。

1 序列

在之前的篇章中,提到了标准类型操作符。此种标准类型操作符一般都能适用于所有的序列类型。那么说一下对所有序列类型都适用的操作符。

1.1 序列类型操作符

以下操作符是按照优先级从高到低的顺序排列的。

1.1.1 成员关系操作符(in, not in)

用于判断一个元素是否属于一个序列的,若满足就返回True,否则返回False

 obj in seq obj not in seq

1.1.2 连接操作符(+)

用于连接一个序列与另一个相同类型的序列。

  seq1 + seq2

注意:
该操作并不是字符串连接最好并且有效的方法。对字符来说,这个操作不如把所有的字符串放在一个列表或可迭代对象中,然后调用一个join方法来把所有内容连接在一起节约内存。

1.1.3 重复操作符(*)

用于多份拷贝一个序列。

   seq * copies_int

1.1.4 切片操作符([],[:],[::])

通过指定下标的方式来获得某个数据元素,或者通过指定下标范围来获得一组序列的元素。这个访问序列的方式叫做切片。

>>> s = 'abcdefgh'>>> s[::-1]'hgfedcba'>>> s[::2]'aceg'

1.2 内建函数

在这一章节中详细讨论跟序列关系紧密的内建函数(BIF)。

1.2.1 序列类型转换工厂函数

list(iter)
把可迭代对象转换成列表
str(obj)
把obj对象转换成字符串
unicode(obj)
把对象转换成Unicode字符串
tuple(iter)
把一个可迭代对象转换成一个元组对象

1.2.2 可操作内建函数

enumerate(iter)
接受一个可迭代对象作为参数,返回一个 enumerate对象,该对象生成由iter每个元素的index值和iter值组成的元组。
len(seq)
返回seq的长度
max(iter,key=None)
返回iter对象中的最大值
min(iter,key=None)
返回iter对象中的最小值
reversed(seq)
接受一个序列作为参数,返回一个以逆序访问的迭代器
sorted(iter,func=None,key=None,reverse=False)
接受一个可迭代对象作为参数,返回一个有序的列表
sum(seq,init=0)
返回seq和可选参数init的总和,其效果等同于reduce(operator.add,seq,init)
zip([it0,it1,…,itN],[it0,it1,…,itN]):
返回一个列表,其第一个元素是it0,it1,…,这些元素的第一个元素组成的一个元组,第二个…,类推

2 字符串

2.1 创建和赋值

创建一个字符串就像使用一个标题一样简单,当然也可以把str()作为工厂方法来创建一个字符串并把它赋值给一个变量。

>>> aString = 'Hello,world!'>>> anotherString = "Python is cool">>> anotherString'Python is cool'>>> s = str(range(4))>>> s'[0,1,2,3]'

2.2 访问值或子串

用索引或切片的方式来获得子串:

>>> aString = 'Hello, World!'>>> aString[0]'H'>>> aString[1:5]'ello'

2.3 改变字符串

可以通过给一个变量赋值(或者重赋值)的方式”更新”一个已有的字符串。在这里的更新并不是真正意义上的“更新”。之前也曾提到字符串变量是不可更新变量。其更新操作实质上是该变量指向新创建的空间,并将该变量原先指向的空间回收。

>>> aString = "Hello, Python!">>> id(aString)35014160>>> aString = "different string altogether">>> id(aString)40750976

2.4 删除字符串

通过赋一个空字符串或者使用del语句来清空或者删除一个字符串

>>> aString = ''>>> aString''>>> del aString>>> aStringTraceback (most recent call last):  File "<pyshell#7>", line 1, in <module>    aStringNameError:name 'aString' is not defined

但在大部分应用程序里,没有必要显式的删除字符串。定义这个字符串的代码最终会结束,那时python会自动释放这些字符串。

2.5 字符串操作符

2.5.1 标准类型操作符

之前提到的标准类型操作符适用于包括标准类型在内的大部分对象。

注意:
在做比较操作的时候,字符串是按照ASCII值的大小做比较的。

2.5.2 序列操作符

切片

>>> aString = "abcdefg">>> aString[2:]"cdefg"

成员操作符

>>> 'bc' in 'bcd'True

成员操作符用于判断一个字符是否出现在另一个字符串中。出现则返回True,否则返回False。注意,成员操作符不是用来判断一个 字符串是否包含另一个字符串的,这样的功能由find()或者index()
连接操作符
推荐使用字符串格式化操作符%,或者把所有的字符串放到一个列表中,然后用一个join()方法来把它们连接在一起。

>>> '%s %s' % ('Spanish', 'Inquisition')'Spanish Inquisition'>>> s = "".join('Spanish','Inquisition','Made Easy')'Spanish Inquisition Made Easy'

重复操作符

>>> 'Ni!' * 2>>> 'Ni!Ni!'

2.5.3 只适用于字符串的操作符

格式化操作符

>>> "MM/DD/YY = %02d/%02d/%d" % (2,15,67)'MM/DD/YY = 02/15/67'>>> 'There are %(howmany)d %(lang)s Quotation Symbols' % {'lang':'Python', 'howmany':3}"There are 3 Python Quotation Symbols"

原始字符串操作符
除了原始字符串符号(引号前面的字母”r”)以外,原始字符串跟普通字符串有着几乎完全相同的语法。
‘r’可以为小写的也可以是大写的,但唯一的要求是必须紧靠在第一个引号前。

>>> '\n''\n'>>> print '\n'>>> r'\n''\\n'>> print r'\n'\n

Unicode字符串操作符
用于把标准字符串或者是包含Unicode字符的字符串转换成完全地Unicode字符串对象。

u'abc'

Unicode操作符可以与原始字符串操作符连接在一起,但必须出现在原始字符串操作符前面

ur'Hello\nWorld!'

2.6 内建函数

2.6.1 标准类型函数

cmp()
根据字符串的ASCII码值进行比较

>>> str1 = 'abc'>>> str2 = 'lmn'>>> cmp(str1, str2)-11

2.6.2 序列类型函数

len()

>>> str1 = 'abc'>>> len(str1)3

max()或min()

>>> str2 = 'lmn'>>> max(str2)n>>> min(str2)l

enumerate()

>>> s = 'foo'>>> for index, value in enumerate(s):>       print index, value0 f1 o2 o

zip()

>>> s, t = 'foa', 'obr'>>> zip(s,t)[('f','o'),('o','b'),('a','r')]

2.6.3 字符串类型函数

raw_input()
内建的raw_input()函数使用给定字符串提示用户 输入并将这个输入返回。

>>> user_input = raw_input("Enter your name:")Enter your name: John Doe>>> user_input'John Doe'

str()或unicode()
用于产生所对应类型的对象
chr(),unichr() and ord()
chr()函数用一个范围在range(256)内的整数做为参数,返回一个对应的字符
unichr()函数返回Unicode字符
ord()函数以一个字符作为参数,返回对应的ASCII数值或者Unicode数值

2.7 字符串内建函数

此处仅介绍些常用的函数,如有需要,请详见书中内容。

方法 描述 capitalize 字符串的第一个字符大写 center 返回一个原字符串居中,并使用空格填充至width长度 count 返回str在string里面出现的次数 decode 以encoding指定的编码格式解码string encode 以encoding指定的编码格式编码string endswith 检查字符串是否以obj结束 startswith 检查字符串是否以obj开头 find 检测str是否包含在string中 index 作用同find()方法,只不过如果str不在string中会报一个异常 isdigit 如果string只包含数字则返回True upper 转换成string中的小写字母为大写 lower 转换成string中的大写字母为小写 join 以string作为分隔符,将seq中所有的元素合并为一个新的字符串 split 以str为分隔符切片string,如果num有指定值,则仅分隔num个子字符串 replace 把string中的str1替换成str2,如果num指定,则替换不超过num次

2.8 三引号

三引号可以包含诸如换行符这样的特殊字符,其语法是一对连续的单引号或者双引号

>>> hi = """hithere""">>> hi 'hi\nthere'>>> print hi'hithere'

2.9 编码与解码

2.9.1 字符编码历程

字符编码历程

2.9.2 字符编码工作方式

用记事本编辑时,从文件读取的UTF-8字符被转换为unicode字符存储到内存里。编辑完成后,再把unicode字符转换为utf-8保存到文件
在线编辑字符转换
浏览网页时,服务器会将动态生成的unicode内容转换为utf-8再传输到浏览器。所以,许多网页的源码上会有<meta charset=”UTF-8”/>表明其用utf-8方式编码。
网页查看字符转换

2.9.3 Python对unicode的支持

由于python的诞生比unicode标准发布的早,所以早期的python并不支持ASCII编码,而是在后来添加了对unicode的支持,用u’…’表示该字符串以unicode表示。
由于python源代码是一个文本文件,所以当源代码中包含中文时,在保存源代码和读取源代码时,都需要尤其注意。
a. 保存源代码
在python中,字符串本身存储的就是字节码。该字节码的格式依赖于输入该字节码的设备所决定。如这段代码是由解释器输入的,那么该字符串的格式就是解释器的编码格式。所以,在保存源代码时需要指定保存为utf-8编码。
b. 读取源代码
当python解释器读取源代码时,为了让它按utf-8编码读取,通常会在文件开头写上这两行:

#! /usr/bin/env python# -*- coding: utf-8 -*-

2.9.4 Python编码与解码问题

在python的编码中,有一个比较重要的问题:

"中文".encode("utf-8")

这里涉及到了一个隐式的类型转化,会将字符串以默认编码方式解码后再进行编码。其相当于

"中文".decode(sys.getdefaultencoding()).encode("utf-8")

大部分情况下,python的默认编码是ascii,不能用于编码中文字符。因此,经常看到的一个错误为

UnicodeDecodeError: 'ascii' codec can't decode byte 0xd6 in position 0: ordinal not in range(128)

2.9.5 格式化

在python中,采用格式化方式和C语言是一致的,用%实现。若字符串内的%仅为普通字符,可用%%表示一个%

>>> "hello, %s, you have %d%% market share" % ("Michael", 100)>'hello, Michael, you have 100% market share'

常见的占位符有:%d(整数)、%f(浮点数)、%s(字符串)、%x(十六进制整数)

python字符串并不是通过NULL或者’\0’来结束的,因此不需要为是否已经添加终结符担心。

3. 列表

列表是能保留任意数目的python对象的灵活容器。

3.1 创建列表类型数据并赋值

可手工写一个列表(空的或者有值的都行),然后赋给一个变量,列表是由方括号([])来定义的。当然,你也可以用工厂方法来创建它。

>>> aList = [123,'abc']>>> list('foo')['f','o','o']

3.2 访问列表中的值

列表的切片操作符([])和索引值或索引值范围一起使用

>>> aList[0]123>>> aList[1:]['abc']

3.3 更新列表

可以通过在等号的左边指定一个索引或者索引范围的方式来更新一个或几个元素,也可以用append()方法来追加元素到列表中

>>> aList[123,'abc',4.56]>>> aList[2] = 'float replacer'[123,'abc','float replacer']>>> aList.append("hi,i'm new here")>>> aList[123,'abc',4.56,"hi,i'm new here"]

还可以通过pop()方法来删除并从列表中返回一个特定对象。一般来说,程序员不需要去删除一个列表对象。列表对象出了作用域后它会被自动析构。

3.4 操作符

3.4.1 标准类型操作符

标准类型操作符适用于包括标准类型在内的大部分对象。

3.4.2序列类型操作符

切片
列表的切片操作返回的是一个对象或者是几个对象的集合,而不是像字符串那样,返回一个字符或者一个子串

>>> num_list = [43,-1.23,-2]>>> num_list[1]-1.23>>> num_list[1:][-1.23,-2]

成员关系操作
用于检查一个对象是否是一个列表的成员

>>> mixup_list[4.0,'beef']>>> 'beef' in mixup_listTrue

连接操作符
用于合并多个列表对象,但是值得注意的是,列表类型的连接操作也只能在同类型之间进行

>>> num_list = [43,-1.23]>>> str_list = ['jack','jumped']>>> num_list + str_list[43,-1.23,'jack','jumped']

其实,我们可以用extend()方法来代替连接操作符把一个列表的内容添加到另一个中。使用extend()方法比连接操作的一个优点是它实际上是把新列表添加到原有的列表里面,而不是像连接操作那样新建一个列表。
重复操作符

>>> num_list * 2>>> num_list[43,-1.23,43,-1.23]

列表解析

>>> [i * 2 for i in [8,-2,5]]>>> [16,-4,10]

3.5 内建函数

3.5.1 标准类型函数

cmp

>>> list1,list2=[123,'xyz'],[456,'abc']>>> cmp(list1,list2)-1

当逐项比较list1和list2时,第一个比较操作发生在两个列表的第一个元素之间。因为123<456,所以list1被认为小于list2。如果比较的值相等,那么两个序列的下一值继续比较,直到不相等的情况出现,或者到达较短的一个序列的末尾。在这种情况下,长的序列被认为是“较大”的。

3.5.2 序列类型函数

len
对于列表或者元组来说,会返回列表或者元组的元素个数。

>>> len(num_list)2

max() and min()

>>> max(num_list)43>>> min(num_list)-1.23

sorted() and reversed()

>>> s = ['They','stamp','them','when',"they're",'small']>>> for t in reverse(s):...     print t,small they're when them stamp They>>> sorted(s)['They','small','stamp','them',"they're",'when'] 

enumerate() and zip()

>>> albums = ['tales','robot','pyramid']>>> for i,album in enumerate(albums):...     print i,album0 tales1 robot2 pyramid>>> fn = ['ian','stuart','david']>>> for i,j in zip(albums,fn)...     print ('%s %s'%(i,j)).title()Tales IanRobot StuartPyramid David

sum()

>>> a = [6,4,5]>>> reduce(operator.add,a)15>>> sum(a)15

list() and tuple()
list()函数和tuple()函数接受可迭代对象(比如另一个序列)作为参数, 并通过浅拷贝数据来创建一个新的列表或者元组。也就是说,虽然前后两个对象有着相同的数据集合,但是变量指向的却不是同一个对象了。

3.5.3 列表类型内建函数

如果不考虑range()函数的话,Python中没有特定用于列表的内建函数。

3.6 列表类型的内建函数

内建函数 描述 append 向列表中添加一个对象obj count 返回一个对象obj在列表中出现的次数 extend 把序列seq的内容添加到列表中 index 返回list[k]=obj的k值 insert 在索引量为index的位置插入对象obj pop 删除并返回指定位置的对象,默认是最后一个对象 remove 从列表中删除obj reverse 原地翻转列表 sort 以指定的方式排序列表中的成员,如果func和key参数指定,则按照指定的方式比较各个元素,如果reverse标志被置为True,则列表以反序排列

注意:
在使用可变对象的方法如sort(),extend()和reverse()时要注意 ,这些操作会在列表中原地执行操作,也就是说现有的列表内容会被改变,但是没有返回值。

3.7 列表的特殊特性

3.7.1 用列表构建其他数据结构

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

4 元组

实际上元组是跟列表非常相近的另一种容器类型。元组与列表的区别在于元组用的是圆括号而列表用的是方括号;功能上,元组和列表相比有一个很重要的区别,元组是一种不可变类型。另外当处理一组对象时,这个组默认是元组类型。

4.1 元组创建并赋值

创建一个元组并给他赋值实际上跟创建一个列表并给它赋值完全一样。除了一点,只有一个元素的元组需要在元组分割符里面加一个逗号,用以防止跟普通的分组操作符混淆。

>>> aTuple = (123,'abc',4.56)>>> tuple('bar')('b','a','r')

4.2 访问元组中的值

元组的切片操作跟列表一样,用方括号作为切片操作符([]),里面写上索引值或者索范围。

>>> aTuple[1:2]('abc',4.56)

4.3 更新元组

元组和字符串属于不可变类型。在对字符串的更新操作中,我们是通过现有字符串的片段再构造一个新字符串的方式解决的。

>>> aTuple = aTuple[0],aTuple[1]>>> aTuple(123,'abc')

如果要删除一个单独的元组元素是不可能的。当然,把不需要的元素丢弃后,重新组成一个元组是没有问题的。
要显示地删除一整个元组,只要用del语句减少对象引用计数。

4.4 元组操作符和内建函数

4.4.1 标准类型操作符,序列类型操作符和内建函数

元组的对象和序列类型操作符还有内建函数跟列表完全一样,可以对元组进行切片操作,合并操作,以及多次拷贝一个元组,还可以检查一个对象是否属于一个元组,进行元组之间的比较。
创建、重复、连接操作

>>> t = (23,-103.4)>>> t * 2(23,-103.4,23,-103.4)>>> t + ('free','easy')(23,-103.4, 'free','easy')

成员关系操作,切片操作

>>> 23 in tTrue>>> 123 in tFalse

内建函数

>>> str(t)(['xyz',123],23,-103.4,'free')>>> len(t)4>>> max(t)'free'>>> min(t)-103.4>>> cmp(t,(['xyz',123],123))-1>>> list(t)[['xyz',123],23,-103.4,'free','easy']

操作符

>>> (4,2) < (3,5)False>>> (2,3) == (3,-1)False

4.4.2 元组类型操作符和内建函数,内建方法

像列表一样,元组也没有自己专用的运算符和内建函数。

4.5 元组的特殊特性

所有的多对象的,逗号分隔的,没有明确用符号定义的,都默认为元组。而所有函数返回的多对象(不包含有符号封装的)都是元组类型。

5 模块

5.1 浅拷贝与深拷贝

>>> person = ['name',['savings',100.00]]>>> hubby = person[:]>>> wifey = list(person)>>> hubby[1][1]=50>>> hubby,wifey(['name',['savings',50.0]],['name',['savings',50.0]])

当我们修改了hubby中的数据后,发现wifey中的数据也被相应修改。原因在于我们仅仅做了个浅拷贝。对一个对象进行浅拷贝其实是新创建了一个类型跟原对象一样,其内容是原对象的引用。换句话说,这个拷贝的对象本身是新的,但是它的内容不是。序列类型对象的浅拷贝是默认类型拷贝,并可以以下几种方式实施:(1)完全切片操作[:];(2)利用工厂函数;(3)使用copy模块的copy函数
在进行浅拷贝时,字符串(不可变变量)会被显式的拷贝,并重新创建了一个字符串对象。而列表元素(可变变量)只是把它的引用复制一下。
如果我们要深拷贝,也就是创建一个新的容器对象,包含原有对象元素(引用)全新拷贝的引用,则需要copy.deepcopy()函数。

copy模块:
copy()进行浅拷贝操作,而deepcopy()进行深拷贝操作。

0 0
原创粉丝点击