列表、元组、字典深入学习:
一、对于列表来讲,有三个内置函数非常有用:filter(),map()和reduce() 1、"filter(function, sequence)"返回一个sequence(序列),包括了给定序列中所有调用function(item)后返回值为true的元素 (如果可能的话,会返回相同的类型).如果 sequence是一个string(字符串)或者tuple(元组),返回值必定是同一类型, 否则,它总是 list。 >>> def f(x):return x % 2 != 0 and x % 3 !=0 ... >>> filter(f,range(2,25)) [5, 7, 11, 13, 17, 19, 23] 2、"map(function, sequence)" 为每一个元素依次调用function(item)并将返回值组成一个链表返回. 例如,以下程序计算立方: >>> def cube(x): return x*x*x ... >>> map(cube,range(1,11)) [1, 8, 27, 64, 125, 216, 343, 512, 729, 1000] 可以传入多个序列,函数也必须要有对应数量的参数,执行时会依次用各序列上对应的元素来调用函数 (如果某些序列比其它的短,就用None来代替).如果把None做为一个函数传入,则直接返回参数做为替代. 例如: >>> seq = range(8) >>> def add(x, y): return x+y ... >>> map(add,seq,seq) [0, 2, 4, 6, 8, 10, 12, 14] 3、"reduce(func, sequence)"返回一个单值,它是这样构造的: 首先以序列的前两个元素调用函数,再以返回值和第三个参数调用,依次执行下去. 例如,以下程序计算1到10的整数之和: >>> def add(x,y): return x+y ... >>> 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 4、列表推导式: 列表推导式提供了一个创建链表的简单途径,无需使用map(),filter()以及lambda. 返回链表的定义通常要比创建这些链表更清晰,每一个链表推导式包括在一个for 语句之后的表达式,零或多个for或if语句. 返回值是由for或if子句之后的表达式得到的元素组成的链表.如果想要得到一个元组,必须要加上括号. >>> vec=[2,4,6] >>> [3*x for x in vec] [6, 12, 18] >>> [3*x for x in vec if x >3] [12, 18] >>> [3*x for x in vec if x <2] [] >>> [[x,x**2] for x in vec] [[2, 4], [4, 16], [6, 36]] >>> [(x,x**2) for x in vec] [(2, 4), (4, 16), (6, 36)] >>> vec1 = [2, 4, 6] >>> vec2 = [4, 3, -9] >>> [x*y for x in vec1 for y in vec2] [8, 6, -18, 16, 12, -36, 24, 18, -54] >>> [x+y for x in vec1 for y in vec2] [6, 5, -7, 8, 7, -5, 10, 9, -3] >>> [vec1[i]*vec2[i] for i in range(len(vec1))] [8, 12, -54] 列表推导式比map()更复杂,可使用复杂的表达式和嵌套函数。 >>> [str(round(355/113.0,i)) for i in range(1,6)] ['3.1', '3.14', '3.142', '3.1416', '3.14159'] 二、其他 1、del语句:从列表中删除指定索引的元素,可删除列表一部分或整个列表,还可以删除整个变量或字典 >>> L1=[2,3,4,5,6] >>> L1 [2, 3, 4, 5, 6] >>> del L1[0] >>> L1 [3, 4, 5, 6] >>> del L1[1:3] >>> L1 [3, 6] >>> del L1 2、sets集合: >>> a = set('abracadabra') >>> b = set('alacazam') >>> a set(['a', 'r', 'b', 'c', 'd']) >>> b set(['a', 'c', 'z', 'm', 'l']) >>> a-b set(['r', 'b', 'd']) >>> a|b set(['a', 'c', 'b', 'd', 'm', 'l', 'r', 'z']) >>> a&b set(['a', 'c']) >>> a^b set(['b', 'd', 'm', 'l', 'r', 'z']) 3、循环相关技术: 在字典中循环时,关键字和对应的值可以使用 iteritems()方法同时解读出来 >>> knights = {'gallahad': 'the pure', 'robin': 'the brave'} >>> for k, v in knights.iteritems(): ... print k, v ... gallahad the pure robin the brave 在列表中循环时,索引位置和对应值可以使用enumerate()函数同时得到 >>> for i, v in enumerate(['tic', 'tac', 'toe']): ... print i,v ... 0 tic 1 tac 2 toe 同时循环两个或更多的序列,可以使用 zip() 整体解读 >>> questions = ['name', 'quest', 'favorite color'] >>> answers = ['lancelot', 'the holy grail', 'blue'] >>> for q, a in zip(questions, answers): ... print 'What is your %s? It is %s.' % (q, a) ... What is your name? It is lancelot. What is your quest? It is the holy grail. What is your favorite color? It is blue. 需要逆向循环序列的话,先正向定位序列,然后调用 reversed() 函数 >>> for i in reversed(xrange(1,27,3)): ... print i ... 25 22 19 16 13 10 7 4 1 要按排序后的顺序循环序列的话,使用sorted()函数,它不改动原序列,而是生成一个新的排好序的序列. >>> basket = ['apple', 'orange', 'apple', 'pear', 'orange', 'banana'] >>> for f in sorted(set(basket)): ... print f ... apple banana orange pear 4、比较操作符和逻辑操作符: 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' 需要注意的是不同类型的对象比较是合法的.输出结果是确定而非任意的:类型按它们的名字排序. 因而,一个链表(list)总是小于一个字符串(string),一个字符串(string)总是小于一个元组(tuple)等等. 数值类型比较时会统一它们的数据类型,所以0等于0.0等等.