当前位置:Linux教程 - Linux综合 - 第五章 Python数据结构

第五章 Python数据结构

  第五章 Python数据结构 last edited 2 months ago by panjy 本章更详细地讨论一些已经讲过的数据类型的使用,并引入一些新的类型。 5.1 列表 列表数据类型还有其它一些方法。下面是列表对象的所有方法: insert(i, x) ---- 在指定位置插入一项。第一自变量是要在哪一个元素前面插入,用下 标表示。例如,a.insert(0, x)在列表前面插入,a.insert(len(a), x)等价于a.append(x) 。 append(x) ---- 等价于a.insert(len(a), x) index(x) ---- 在列表中查找值x然后返回第一个值为x的元素的下标。没有找到时出错。 remove(x) ---- 从列表中删去第一个值为x的元素,找不到时出错。 sort() ---- 对列表元素在原位排序。注意这个方法改变列表,而不是返回排序后的列表。 reverse() ---- 把列表元素反序。改变列表。 count(x) ---- 返回x在列表中出现的次数。   下例使用了所有的列表方法: >>> a = [66.6, 333, 333, 1, 1234.5] >>> print a.count(333), a.count(66.6), a.count('x') 2 1 0 >>> a.insert(2, -1) >>> a.append(333) >>> a [66.6, 333, -1, 333, 1, 1234.5, 333] >>> a.index(333) 1 >>> a.remove(333) >>> a [66.6, -1, 333, 1, 1234.5, 333] >>> a.reverse() >>> a [333, 1234.5, 1, 333, -1, 66.6] >>> a.sort() >>> a [-1, 1, 66.6, 333, 333, 1234.5] 5.1.1 函数程序设计工具 Python中有一些函数程序设计风格的东西,例如前面我们看到的lambda形式。关于列表有 三个非常有用的内置函数:filter(), map()和redUCe()。 “filter(函数, 序列)”返回一个序列(尽可能与原来同类型),序列元素是原序列中由 指定的函数筛选出来的那些,筛选规则是“函数(序列元素)=true”。filter()可以用来取出 满足条件的子集。例如,为了计算一些素数: >>> def f(x): return x % 2 != 0 and x % 3 != 0 ... >>> filter(f, range(2, 25)) [5, 7, 11, 13, 17, 19, 23] “map(函数,序列)”对指定序列的每一项调用指定的函数,结果为返回值组成的列表。map() 可以对序列进行隐式循环。例如,要计算三次方,可用: >>> def cube(x): return x*x*x ... >>> map(cube, range(1, 11)) [1, 8, 27, 64, 125, 216, 343, 512, 729, 1000] 可以有多个序列作为自变量,这时指定的函数必须也有相同个数的自变量,函数从每个序 列分别取出对应元素作为自变量进行调用(如果某个序列比其它的短则取出的值是None)。 如果指定的函数是None,map()把它当成一个返回自己的自变量的恒同函数。在函数用None的 情况下指定多个序列可以把多个序列搭配起来,比如“map(None, list1, list2)”可以把两 个列表组合为一个成对值的列表。见下例: >>> seq = range(8) >>> def square(x): return x*x ... >>> map(None, seq, map(square, seq)) [(0, 0), (1, 1), (2, 4), (3, 9), (4, 16), (5, 25), (6, 36), (7, 49)] “reduce(函数, 序列)”用来进行类似累加这样的操作,这里的函数是一个两个子变量的 函数,reduce()先对序列的前两项调用函数得到一个结果,然后对结果和序列下一项调用函 数得到一个新结果,如此进行到序列尾部。例如,要计算1到10的和: >>> def add(x,y): return x+y ...
[1] [2] [3] 下一页 

>>> reduce(add, range(1, 11)) 55 如果序列中只有一个值则返回这个值,序列为空时会产生例外。可以指定第三个自变量作 为初始值。有初始值时对空序列函数将返回初始值,否则函数先对初始值和序列第一项作用 ,然后对结果和序列下一项作用,如此进行到序列尾。例如: >>> def sum(seq): ... def add(x,y): return x+y ... return reduce(add, seq, 0) ... >>> sum(range(1, 11)) 55 >>> sum([]) 0 5.2 del语句 上面我们看到,列表的remove()方法可以从列表中删去某个取值的项,我们还可以用del 语句来删除指定下标的项。也可以用del语句从列表中删除一个片断(前面我们是用给片断赋 空列表的办法删除片断的)。例如: >>> a [-1, 1, 66.6, 333, 333, 1234.5] >>> del a[0] >>> a [1, 66.6, 333, 333, 1234.5] >>> del a[2:4] >>> a [1, 66.6, 1234.5] del也可以用来删除整个变量,例如: >>> del a 变量删除以后再引用该变量就会出错(除非又给它赋值了)。后面我们还会看到del的其 它一些应用。 5.3 序表和序列 我们看到列表和字符串有许多共同点,例如,下标和片断运算。它们都属于序列数据类型 。因为Python是一个正在不断发展的语言,以后还可能会加入其它的序列数据类型。现在还 有一种标准的序列数据类型,称为序表(tuple)。 序表由一系列值用逗号分隔而成,例如: >>> t = 12345, 54321, 'hello!' >>> t[0] 12345 >>> t (12345, 54321, 'hello!') >>> # 序表允许嵌套: ... u = t, (1, 2, 3, 4, 5) >>> u ((12345, 54321, 'hello!'), (1, 2, 3, 4, 5)) 输出的序表总是用括号包围,这样可以保证嵌套序表得以正确解释。输入时可以有括号也 可以没有括号,当经常是必须有括号(如果序表是一个大表达式的一部分)。 序表有许多用处,例如,(x,y)坐标对,数据库中的职工纪录,等等。序表与字符串一 样是不可变的:不允许对序表的某一项赋值。 生成序表时对0项或1项的序表有特殊的规定:空序表用一对空括号表示;只有一项的序表 用一个之后面跟一个抖好表示(指把这个值放在括号内是不够的)。这样写不够美观,但很 有效。例如: >>> empty = () >>> singleton = 'hello', # <-- note trailing comma >>> len(empty) 0 >>> len(singleton) 1 >>> singleton ('hello',) 语句t = 12345, 54321, 'hello!'是序表打包的一个实例:12345, 54321和'hello!'这些 值被打包进了一个序表中。相反的操作也是允许的,例如: >>> x, y, z = t 这叫做序表解包。序表解包要求等号左边的变量个数等于序表的长度。注意多重赋值只是 序表打包和序表解包的联合使用。有时也对列表进行类似操作,即列表解包。只要把各变量 写成一个列表就可以进行解包: >>> a = ['spam', 'eggs', 100, 1234] >>> [a1, a2, a3, a4] = a 5.4 字典 Python内置的另一个有用的数据类型是字典。字典在其它语言中有时被称为“关联记忆” 或“关联数组”。字典不象序列,它不是用在一个范围之内的数字下标来索引,而是用键值 来索引,键值可以是任何不可变类型。字符串和数值总可以作键值。如果序表只包含字符串 、数值或序表则序表也可以作键值使用。列表不能用作键值,因为列表可以用其append()方 法就地改变值。 最好把字典看成是一系列未排序的“键值:值”的集合,在同一字典内键值是互不相同的 。一对空大括号产生一个空字典:{}。在大括号内加入用逗号分开的“键值:值”对可以在 字典内加入初始的键值和值对,字典在输出时也是这样显示的。对字典的主要操作是以某个 键值保存一个值,以及给定键值后查找对应的值。也可以用del删除某个键值:值对。如果用 一个已有定义的键值保存某个值则原来的植被遗忘。用不存在的键值去查找会出错。
上一页 [1] [2] [3] 下一页 

字典对象的keys()方法返回字典中所有键值组成的列表,次序是随机的。需要排序时只要 对返回的键值列表使用sort()方法。为了检查某个键值是否在字典中,使用字典的has_key() 方法。 下面是字典使用的一个简单例子: >>> tel = {'jack': 4098, 'sape': 4139} >>> tel['guido'] = 4127 >>> tel {'sape': 4139, 'guido': 4127, 'jack': 4098} >>> tel['jack'] 4098 >>> del tel['sape'] >>> tel['irv'] = 4127 >>> tel {'guido': 4127, 'irv': 4127, 'jack': 4098} >>> tel.keys() ['guido', 'irv', 'jack'] >>> tel.has_key('guido') 1 5.5 条件的进一步讨论 在while语句和if语句中使用的条件除了可以使用比较之外还可以包含其它的运算符。比 较运算符“in”和“not in”可以检查一个值是否在一个序列中。运算符“is”和“is not ”比较两个对象是否恰好是同一个对象,这只对象列表这样的可变对象有意义。所有比较运 算优先级相同,而比较运算的优先级比所有数值运算优先级低。 比较允许连写,例如,a < b == c检查是否a小于等于b而且b等于c。 比较可以用逻辑运算符and和or连接起来,比较的结果(或其它任何逻辑表达式)可以用not 取反。逻辑运算符又比所有比较运算符低,在逻辑运算符中,not优先级最高,or的优先级最 低,所以“A and not B or C”应解释为“(A and (not B)) or C”。当然,可以用括号来 表示所需的组合条件。 逻辑运算符and和or称为“短路”运算符:运算符两侧的表达式是先计算左边的,如果左 边的结果已知则整体结果已知就不再计算右边的表达式。例如,如果A和C为真而B为假则“A and B and C”不会计算表达式C。一般地,当短路运算符的运算结果不是用作逻辑值的时候 返回的是最后求值的那个表达式的值。 可以把比较或其它逻辑表达式的结果赋给一个变量。例如: >>> string1, string2, string3 = '', 'Trondheim', 'Hammer Dance' >>> non_null = string1 or string2 or string3 >>> non_null 'Trondheim' 注意Python和C不同,表达式中不能进行赋值。 5.6 序列与其它类型的比较 序列对象可以和其它同序列类型的对象比较。比较使用字典序:先比较最前面两项,如果 这两项不同则结果可以确定;如果这两项相同,就比较下面的两项,如此下去,直到有一个 序列到头为止。如果某两项本身也是同类型的序列,则进行递归的字典序比较。如果两个序 列的所有各项都相等,则这两个序列相等。如果一个序列是另一个序列的一个初始子序列, 短的一个是较小的一个。字符串的字典序比较按各个字符的ASCII次序进行。下面是一些序列 比较的实例: (1, 2, 3) < (1, 2, 4) [1, 2, 3] < [1, 2, 4] 'ABC' < 'C' < 'Pascal' < 'Python' (1, 2, 3, 4) < (1, 2, 4) (1, 2) < (1, 2, -1) (1, 2, 3) = (1.0, 2.0, 3.0) (1, 2, ('aa', 'ab')) < (1, 2, ('abc', 'a'), 4) 注意不同类型的对象比较目前也是合法的。结果是确定的但却没有什么意义:不同类型是 按类型的名字排序的。所以,列表(list)总是小于字符串(string),字符串总是小于序 表(tuple),等等。但是程序中不能依赖这样的比较规则,语言实现可能会改变。不同的数 值类型可以按数值来比较,所以0等于0.0,等等。

(出处:http://www.sheup.com)


上一页 [1] [2] [3] 

>>> non_null 'Trondheim' 注意Python和C不同,表达式中不能进行赋值。 5.6 序列与其它类型的比较 序列对象可以和其它同序列类型的对象比较。比较使用字典序:先比较最前面两项,如果 这两项不同则结果可以确定;如果这两项相同,就比较下面的两项,如此下去,直到有一个 序列到头为止。如果某两项本身也是同类型的序列,则进行递归的字典序比较。如果两个序 列的所有各项都相等,则这两个序列相等。如果一个序列是另一个序列的一个初始子序列, 短的一个是较小的一个。字符串的字典序比较按各个字符的ASCII次序进行。下面是一些序列 比较的实例: (1, 2, 3) < (1, 2, 4) [1, 2, 3] < [1, 2, 4] 'ABC' < 'C' < 'Pascal' < 'Python' (1, 2, 3, 4) < (1, 2, 4) (1, 2) < (1, 2, -1) (1, 2, 3) = (1.0, 2.0, 3.0) (1, 2, ('aa', 'ab')) < (1, 2, ('abc', 'a'), 4) 注意不同类型的对象比较目前也是合法的。结果是确定的但却没有什么意义:不同类型是 按类型的名字排序的。所以,列表(list)总是小于字符串(string),字符串总是小于序 表(tuple),等等。但是程序中不能依赖这样的比较规则,语言实现可能会改变。不同的数 值类型可以按数值来比较,所以0等于0.0,等等。

(出处:http://www.sheup.com)


上一页 [1] [2] [3] [4] 

'ABC' < 'C' < 'Pascal' < 'Python' (1, 2, 3, 4) < (1, 2, 4) (1, 2) < (1, 2, -1) (1, 2, 3) = (1.0, 2.0, 3.0) (1, 2, ('aa', 'ab')) < (1, 2, ('abc', 'a'), 4) 注意不同类型的对象比较目前也是合法的。结果是确定的但却没有什么意义:不同类型是 按类型的名字排序的。所以,列表(list)总是小于字符串(string),字符串总是小于序 表(tuple),等等。但是程序中不能依赖这样的比较规则,语言实现可能会改变。不同的数 值类型可以按数值来比较,所以0等于0.0,等等。

(出处:http://www.sheup.com/)


上一页 [1] [2] [3] [4] [5]