1、Python程序设计Programming in Python主讲:庞胜利2第三章 常用数据结构 数字 字符串 列表 元组 字典为什么使用内置对象 内置对象使程序更容易编写内置对象可以满足大部分的应用 内置对象往往比定制的数据结构更有效率速度方面,内置对象优化了用C实现的数据结构算法 内置对象是语言的标准的一部分数字 Python提供了常用的数字类型:整数、浮点数以及与之相关的语法和操作 允许使用八进制、十六进制常量 提供了复数类型 提供了无穷精度的长度类型(只要内存空间允许,可以增长成为任意位数的整数)数字常量数字数字常量常量1234,-24,0一般整数(c语言长整型)99999999999
2、9999999999999999L98888888888888888l长整型数(无限大小)1.23,3.14e-10,4E210,4.0e+210浮点数(C语言双精度浮点数)0177,0 x9ff八进制、十六进制3+4j,3.0+4.0j,3J复数常量内置数学工具和扩展 表达式操作符+、-、*、/、*内置数学函数pow、abs 公用模块random、math等 专业扩展NumPy矩阵、向量处理等变量和基本的表达式 变量就是用来记录程序中的信息,它的特点:变量像对象一样不需要声明变量在第一次赋值时创建变量在表达式中使用将被替换为他们的值变量在表达式中使用以前必须已经赋值数字的基本应用 a=3 b
3、=4 a+14 a-12 b*312 b/22 a%21 b*216 2.0*b16.0 c*2Traceback(most recent call last):File,line 1,in NameError:name c is not defined b/2+a5 b/(2.0+a)0.80000000000000004 print b/(2.0+a)0.8数字显示的格式 num=1/3.0 num0.33333333333333331 print num0.333333333333%e%num3.333333e-01%2.2f%num0.33 八进制、十六进制 将一个整数变为其八进制、十
4、六进制的数字字符串oct hex 将一个数字的字符串变换成一个整数,第二个参数用于指示变换后的数字的进制 用字符串格式表达式转换成八进制、十六进制的字符串 oct(64)0100 hex(64)0 x40 int(0100)100 int(0100,8)64 int(0 x40,16)64%o%x%X%(64,64,255)100 40 FF数学内置函数和内置模块 math模块-普通数学函数 cmath模块-处理复数的模块 acos,fsum,acosh,hypot,asin,isinf,asinh,isnan,atan,ldexp,atan2,log,atanh,log10,ceil,log
5、1p,copysign,modf,cos,pi,cosh,pow,degrees,radians,e,sin,exp,sinh,fabs,sqrt,factorial,tan,floor,tanh,fmod,trunc frexp,acos,log,acosh,log10,asin,phase,asinh,pi,atan,polar,atanh,rect,cos,sin,cosh,sinh,e,sqrt,exp,tan,isinf,tanh isnan,random模块 用于产生随机数 import random random.random()0.33452758558893336 rando
6、m.randint(1,10)5 random.choice(a,b,c)c字符串 在第二章已经简单介绍过字符串 简单回顾字符串常量:单引号双引号三引号转义自然字符串Unicode字符串字符串转义 转义字符同C语言的转义字符转义意义 newline行连续反斜线单引号”双引号a响铃b倒退f换页n新行转义意义r返回t水平制表符v垂直制表符uhhhhUnicode16位的十六进制值UhhhhUnicode32位的十六进制值xhh十六进制值0oo八进制值0Nullother不转义(保留)字符串基本操作+字符串合并*字符串重复 len(abc)3 abc+defabcdef abc defabcdef
7、hello*4hellohellohellohello abc+9Traceback(most recent call last):File,line 1,in TypeError:cannot concatenate str and int objects字符串基本操作 可以用for语句在一个字符串中进行迭代,并使用in表达式操作符进行成员关系的测试,这实际上是一种搜索 for循环指派了一个变量去获取一个序列其中的元素,并对每一个元素执行一个或多个语句,变量c相当于在字符串中步进的指针 s=hello for c in s:.print c,.h e l l o h in sTrue b i
8、n sFalse字符串索引和分片 字符串是字符的有序集合,能够通过其位置来获得他们的元素 Python中字符串中的字符是通过索引提取的 索引从0开始,但不同于C语言的是可以取负值,表示从末尾提取,最后一个是-1,前一个是-2,依次类推,认为是从结束处反向计数 s=spam s0s s1p s-1m s-2a字符串索引和分片 分片:从字符串中分离提取了一部分内容(子字符串);可以用于提取部分数据,分离出前、后缀等场合。当使用一对以冒号分隔的偏移索引字符串这样的序列对象时,Python就返回一个新的对象,其中包含了以这对偏移所标识的连续的内容。左边的偏移被取作是下边界(包含下边界在内),而右边的偏
9、移被认为是上边界(不包括上边界在内)。如果被省略上下边界的默认值分别对应为0和分片对象的长度 s=spam s1:3pa s1:pam s:-1spa s:spam索引和分片的总结 索引(si)获取特定偏移的元素第一个元素的偏移为0负偏移索引意味着从最后或右边反向进行计数s0获取第一个元素s-2获取倒数第二个元素 分片(si:j)提取对应的部分作为一个序列上边界并不包含在内分片的边界默认为0和序列的长度,如果没有给出的话s1:3获取从偏移为1开始,直到但不包含偏移为3的元素s1:获取了从偏移为1直到末尾之间的元素s:3获取从偏移为0直到但不包含偏移为3的元素s:-1获取从偏移为0直到但不包含最
10、后一个元素之间的元素s:获取从偏移为0直到末尾之间的所有元素分片的扩展形式 在Python2.3后,分片表达式增加了一个可选的第三个索引,用作步进选取 完整形式为:XI:J:K,这表示:索引(获取)对象X中元素,从偏移为I直到J-1,每隔K元素索引一次 K默认为1,这就是通常在切片中从左至右提取每个元素的原因 步进为负数表示将会从右至左进行而不是从左至右分片的扩展形式 X1:10:2会取出X中,偏移量1-9之间,间隔一个元素的元素,即获取偏移量为1、3、5、7、9 s=abcdefghijklmnop s1:10:2bdfhj s:2acegikmo s=0123456 s:0123456 s
11、:-16543210 s:-26420 s1:5:-1 s5:1:-15432 s9:-16543210 s6:-1:-1 s6:-2:-16字符串转化 Python不允许字符串和数字直接相加。这是有意设计的,因为+既能够进行加法运算也能够进行合并运算,这样的语法会变得模棱两可,因此,Python将其作为错误处理,在Python中,如果让操作变得复杂或含糊,就会避免这样的语法 15+1Traceback(most recent call last):File,line 1,in TypeError:cannot concatenate str and int objects字符串转化 如果用户
12、从文件或用户界面得到一个作为字符串的数字,怎么把这个字符串变为数字型呢?这就用到类型的转换函数 s=42 type(s)i=int(s)type(i)s1=str(i)type(s1)s=15 s+1Traceback(most recent call last):File,line 1,in TypeError:cannot concatenate str and int objects int(s)+116通过明确的手动类型转换再进行+操作 常用的类型转换还有字符串到浮点型的转换 之后会深入学习内置的eval函数,用于运行一个包含了Python表达式代码的字符串 s=15.0 float(
13、s)15.0 eval(12)12 eval(12+3)15字符串代码转换 单个字符可以通过ord函数转换为对应的ASCII数值(整数)chr函数相反,可以将一个整数转换为对应的字符 ord(a)97 chr(97)a修改字符串缺省情况下,字符串对象是“不可变序列”,不可变的意思是不能实地的修改一个字符串那如何改变一个字符串呢?这就要利用合并、分片这样的工具来建立并赋值给一个新的字符串;必要的话,可以将结果赋值给字符串最初的变量名 s=spam s0=xTraceback(most recent call last):File,line 1,in TypeError:str object do
14、es not support item assignment s=spam s=s+SPAM sspamSPAM s=s:4+OK!+s-1 sspamOK!M修改字符串 每修改一次字符串就生成一个新的字符串对象,这看起来好像会造成效率下降,其实,在Python内部会自动对不再使用的字符串进行垃圾回收,所以,新的对象重用了前面已有字符串的空间 Python的效率比我们想象的要好字符串格式化 Python可以用%操作符编写格式化的字符串 格式化字符串:1、在%操作符左侧放置一个需要进行格式化的字符串,这个字符串带有一个或多个嵌入的转换目标,都以%开头,如%d、%f等2、在%操作符右侧放置一个对象
15、(或多个,在括号内),这些对象会被插入到左侧格式化字符串的转换目标的位置上 bookcount=10 there are%d books%bookcountthere are 10 books字符串格式化%d%s%d you%(1,spam,4)1 spam 4 you%s-%s-%s%(42,3.1415926,1,2,3)42-3.1415926-1,2,3左侧的目标位置都要求是%s(字符串),这就表示要将右边的对象都转换为字符串另外要注意的是,格式化总会返回新的字符串作为结果,另外要注意的是,格式化总会返回新的字符串作为结果,而不是对左侧的字符串进行修改,由于字符串是不可变的;而不是对左
16、侧的字符串进行修改,由于字符串是不可变的;因此,如果需要的话,可以分配一个变量名来保持结果因此,如果需要的话,可以分配一个变量名来保持结果字符串格式化ConversionMeaningdSigned integer decimal.iSigned integer decimal.oSigned octal value.uObsolete type it is identical to d.xSigned hexadecimal(lowercase).XSigned hexadecimal(uppercase).eFloating point exponential format(lowerca
17、se).EFloating point exponential format(uppercase).fFloating point decimal format.FFloating point decimal format.gFloating point format.Uses lowercase exponential format if exponent is less than-4 or not less than precision,decimal format otherwise.GFloating point format.Uses uppercase exponential fo
18、rmat if exponent is less than-4 or not less than precision,decimal format otherwise.cSingle character(accepts integer or single character string).rString(converts any Python object using repr().sString(converts any Python object using str().%No argument is converted,results in a%character in the res
19、ult.字符串的方法capitalize,将首字母大写 lower,将字符串中所有字符小写 center,填充为指定长度的字符串,并将原字符串放中间 lstrip,去掉字符串左边指定的字符串,去掉参数所有字符的组合 count,返回参数在字符串中出现的次数 partition,将字符串从指定字符串隔开,结果为3元组 decode,按指定格式编码 replace,替换指定的子字符串 encode,按指定格式解码 rfind,查找最右边的指定的子字符串 endswith,是否以参数指定的字符串结尾 rindex,和rfind类似,只是如果找不到触发异常 expandtabs,rjust,右对齐,如
20、果不够长填充指定的字符 find,在字符串中查找指定的子字符串,并返回索引 rpartition,类似于partition,只是从右边开始查找指定字符串 format,格式化 The sum of 1+2 is 0.format(1+2)rsplit,用指定字符分割字符串,并返回列表,如果超过指定数目,只取右边的结果 index,和find相同,但如果找不到的话触发异常 rstrip,类似lstrip,只是去掉右边指定字串 isalnum,字符串是否全是字母和数字 split,将字符串用指定字符分割,返回列表 isalpha,字符串是否全是字母 splitlines,将一个字符串分割为多个字符
21、串的列表,此字符串必须含有n isdigit,字符串是否全是数字(不包括小数点)startswith,字符串是否以指定前缀开始 islower,字符串是否全是小写 strip,去掉字符串前后的指定字符串 isspace,字符串是否全是空格 swapcase,将字符串大小写互换 istitle,字符串单词是否全部首个字符大写 title,将每个单词首字母大写 isupper,字符串是否全部是大写 translate,字符的转换,必须要有转换的码表 join,将列表、元组等元素连接起来 upper,将字符串大写 ljust,靠左对齐,如果不够长填充指定的字符 zfill,安指定宽度在字符串左边填充
22、0字符串总结 1、如何将字符转为ASCII码?如何反向转换,将数字转换为字符?2、在Python中,如何修改字符串?3、已知字符串s的值为“s,pa,m”,如何将其用“,”分割成列表?列表(list)列表是Python中最具灵活性的有序集合对象类型。和字符串不同的是,列表可以包含任何种类的对象:数字、字符串、自定义对象甚至其他列表 列表是可变对象,支持在原处修改,可以通过指定的偏移值和分片、列表方法调用、删除语句等方法实现列表的主要性质 任意对象的有序集合从功能是看,列表就是收集其他对象的地方,可以他们看成数组;同时,列表所包含的每一项都保持了从左到右的位置顺序(也就是说,它们是序列)通过偏移
23、读取和字符串一样,可以通过列表对象的偏移对其进行索引,从而读取对象的一部分内容。当然也可以执行诸如分片和合并之类的操作。列表的主要性质 可变长度、异构以及任意嵌套和字符串不同,列表可以根据需要增长或缩短(长度可变),并且可以包含任何类型的对象,并支持任意的嵌套。可变序列列表支持在原处的修改,也可以响应所有针对字符串序列的操作,如索引、分片以及合并。实际上,序列操作在列表与字符串中工作方式相同。唯一区别是:当合并或分片应用于列表时,返回新的列表而不是新的字符串。当然,支持某些字符串不支持的操作。常用列表常量和操作操作解释L1=一个空的列表L2=0,1,2,3四元素列表L3=abc,10,def,
24、ghi嵌套列表L2i索引L3ij索引的索引L2i:j分片len(L2)求长度L1+L2合并L2*3重复列表的方法 append(x)把一个元素添加到列表的结尾,相当于alen(a):=x extend(L)通过添加指定列表的所有元素来扩充列表,相当于alen(a):=L insert(i,x)在指定位置插入一个元素。第一个参数是准备插入到其前面的那个元素的索引,例如a.insert(0,x)会插入到整个链表之前,而a.insert(len(a),x)相当于a.append(x)。列表的方法 remove(x)删除链表中值为x的第一个元素。如果没有这样的元素,就会返回一个错误。pop(i)从链表
25、的指定位置删除元素,并将其返回。如果没有指定索引,a.pop()返回最后一个元素。元素随即从链表中被删除。(方法中i两边的方括号表示这个参数是可选的,而不是要求输入一对方括号,会经常在Python库参考手册中遇到这样的标记。)列表的方法 index(x)返回链表中第一个值为x的元素的索引。如果没有匹配的元素就会返回一个错误。count(x)返回x在链表中出现的次数。sort()对链表中的元素进行适当的排序。reverse()倒排链表中的元素。列表的方法 a=66.6,333,333,1,1234.5 print a.count(333),a.count(66.6),a.count(x)2 1
26、0 a.insert(2,-1)a.append(333)a66.599999999999994,333,-1,333,1,1234.5,333 a.index(333)1 a.remove(333)a66.599999999999994,-1,333,1,1234.5,333 a.reverse()a333,1234.5,1,333,-1,66.599999999999994 a.sort()a-1,1,66.599999999999994,333,333,1234.5把列表当作堆栈使用 链表方法使得链表可以很方便的做为一个堆栈来使用,堆栈作为特定的数据结构,最先进入的元素最后一个被释放(后
27、进先出)。用append()方法可以把一个元素添加到堆栈顶。用不指定索引的pop()方法可以把一个元素从堆栈顶释放出来。举例:st=3,4,5 st.append(6)st.append(7)st3,4,5,6,7 st.pop()7 st3,4,5,6 st.pop()6 st.pop()5 st3,4把列表当作队列使用 也可以把链表当做队列使用,队列作为特定的数据结构,最先进入的元素最先释放(先进先出)。使用append()方法可以把元素添加到队列最后,以0为参数调用pop()方法可以把最先进入的元素释放出来。queue=a,b,c queue.append(d)queue.append(
28、e)queuea,b,c,d,e queue.pop(0)a queueb,c,d,e queue.pop(0)b queuec,d,e删除列表元素 可以用del进行 可以删除某个索引的元素或切片元素 lst=1,2,3 lst1,2,3 del lst1 lst1,3 lst.append(4)lst1,3,4 del lst0:lst元组 我们知道链表和字符串有很多通用的属性,例如索引和切片操作。它们是序列类型中的两种。因为Python是一个在不断进化的语言,也会加入其它的序列类型,另一种标准序列类型:元组。元组简介 一个元组由数个逗号分隔的值组成,例如:t=12345,54321,hel
29、lo t012345 t(12345,54321,hello)u=t,(1,2,3)u(12345,54321,hello),(1,2,3)元组简介 如上所示,元组在输出时总是有括号的,以便于正确表达嵌套结构。在输入时,有或没有括号都可以,不过经常括号都是必须的(如果元组是一个更大的表达式的一部分)。元组 元组有很多用途。例如(x,y)坐标点,数据库中的员工记录等等。元组就像字符串,不可改变:不能给元组的一个独立的元素赋值(尽管可以通过联接和切片来模仿)可以通过包含可变对象来创建元组,例如链表。lst=1,2,3 t=tuple(lst)t(1,2,3)元组 一个特殊的问题是构造包含零个或一个
30、元素的元组:为了适应这种情况,语法上有一些额外的改变。一对空的括号可以创建空元组;要创建一个单元素元组可以在值后面跟一个逗号(在括号中放入一个单值是不够的)。丑陋,但是有效。例如:emp=()emp()single=a,#len(emp)0 len(single)1 single(a,)元组封装和解封 语句t=12345,54321,hello!是元组封装(sequence packing)的一个例子:值12345,54321 和hello!被封装进元组。其逆操作可能是这样:这个调用被称为序列拆封非常合适。序列拆封要求左侧的变量数目与序列的元素个数相同。t=(1,2,3)x,y,z=t pri
31、nt x,y,z1 2 3元组封装和解封 拆封和封装一点不对称:封装多重参数通常会创建一个元组,而拆封操作可以作用于任何序列。t=1,2,3 x,y,z=t print x,y,z1 2 3 s=123 x,y,z=s print x,y,z1 2 3字典 另一个非常有用的Python内建数据类型是字典。字典在某些语言中可能称为“联合内存”(“associative memories”)或“联合数组”(“associative arrays”)。字典类似于通过联系人名字查找地址和联系人详细情况的地址簿,即:我们把键键(名字)和值值(详细情况)联系在一起。注意,键必须是唯一的,就像如果有两个人恰
32、巧同名的话,将无法找到正确的信息。字典 序列是以连续的整数为索引,与此不同的是,字典以关键字为索引 关键字可以是任意不可变类型,通常用字符串或数值。如果元组中只包含字符串和数字,它可以做为关键字,如果它直接或间接的包含了可变对象,就不能当做关键字 不能用列表做关键字,因为链表可以用它们的append()和extend()方法,或者用切片、或者通过检索变量来即时改变 基本说来,应该只使用简单的对象作为键字典 理解字典的最佳方式是把它看做无序的(关键字:值)对集合,关键字必须是互不相同的(在同一个字典之内)。一对大括号创建一个空的字典:。字典 字典的主要操作是依据关键字来存储和析取值。也可以用de
33、l来删除(关键字:值)对 如果使用一个已经存在的关键字存储新的值或对象,以前为该关键字分配的值就会被遗忘。试图析取从一个不存在的关键字中读取值会导致错误。字典 字典的keys()方法返回由所有关键字组成的列表,该列表的顺序不定(如果需要它有序,只能调用返回列表的sort()方法)使用字典的has_key()方法可以检查字典中是否存在某一关键字 字典的values()方法返回字典内所有的值 字典的get()方法可以根据关键字返回值,如果不存在输入的关键字,返回None字典例子 tel=jack:4098,shy:4139 telgree=4127 telgree:4127,jack:4098,s
34、hy:4139 teljack4098 del telshy telgree:4127,jack:4098 telirv=4127 telgree:4127,irv:4127,jack:4098 tel.keys()jack,irv,gree tel.has_key(gree)True tel.has_key(lee)False字典 字典的update(anothordict)方法类似于合并,它把一个字典的关键字和值合并到另一个,盲目的覆盖相同键的值 telgree:4127,irv:4127,jack:4098 tel1=gree:5127,pang:6008 tel.update(tel1)telgree:5127,irv:4127,jack:4098,pang:6008字典 字典的pop()方法能够从字典中删除一个关键字并返回它的值,类似于列表的pop方法,只不过删除的是一个关键字而不是位置 telgree:5127,irv:4127,jack:4098,pang:6008 tel.pop(gree)5127 telirv:4127,jack:4098,pang:6008 tel.pop(li)Traceback(most recent call last):File,line 1,in KeyError:li本章结束,谢谢!