Python Tutorial 实践(4)

又有很长的时间过去了,继续推荐Python Tutorial的进程。

本文主要针对官方Python Tutorial中第5小节的内容进行有选择性的分析,还是遵循本系列文档的风格,所讨论的内容都是给我留下一些印象的,或者是一般不太注意的。若有错误,欢迎大家批评指正。

List类型

应该说如果前4小节的内容您都理解透彻了,那么用Python来写一些基本的程序应该没什么太大问题。从本小节开始,Tutorial中的内容都是更详细的讨论Python的某些特点。本节的一开始对List类型进行了更详细的讨论。List类型主要有以下常见的方法:

list.append(x) #在列表末尾添加元素x
list.extend(L) #将列表L追加在当前列表后,以扩展列表
list.insert(i, x) 
list.remove(x)
list.pop([i]) 
list.index(x) 
list.count(x) 
list.sort() 
list.reverse() 

其中的[i]表示该参数是可选的,相信通过这些方法的名字你就可以很好的明白其作用。这里罗列出来也算是一个基本的回顾。

可以发现,可以通过List的append和pop方法将一个List当作一个栈来用。不仅如此,通过其它库的辅助,List还可以作为队列来使用。

为了使List可以用作队列,我们通过以下示例来说明:

>>> from collections import deque
>>> queue = deque(["Eric", "John", "Michael"])
>>> queue.append("Terry")           # Terry arrives
>>> queue.append("Graham")          # Graham arrives
>>> queue.popleft()                 # The first to arrive now leaves
'Eric'
>>> queue.popleft()                 # The second to arrive now leaves
'John'
>>> queue                           # Remaining queue in order of arrival
deque(['Michael', 'Terry', 'Graham'])

可以发现,为了将其用作队列,我们导入deque(双端队列)这个库,这样就可以通过append和popleft实现队列的基本功能。

函数式编程工具

在Python中有三个非常有用的内建函数可以和List类型一同使用:filer(),map()和reduce()。

filter(function, sequence)返回一个序列,其是有sequence组成的,并且对于sequence里的每一个item,function(item)为true。除非sequence是一个string或tuple,那样的话其返回类型还是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]

可以看到,f(x)返回的结果为不能被2和3整除的数,filter返回的就是2-25之间不能被2和3整除的数。当然,这里的f可以用lamda表达式来代替,这里不讨论这个问题。

map(function, sequence)也是返回一个序列,基本仿照之前filter函数的意义,其返回对sequence中的item调用function后的结果。通过filter(过滤)和map(映射)的中文含义我们也应该可以理解它们的行为。对map(),举例如下:

>>> def cube(x): return x*x*x
...
>>> map(cube, range(1, 11))
[1, 8, 27, 64, 125, 216, 343, 512, 729, 1000]

对于sequence参数,可以不止有一个。当然,此时就要求function函数的参数也是和sequence参数的个数是匹配的:

>>> seq = range(8)
>>> def add(x, y): return x+y
...
>>> map(add, seq, seq)
[0, 2, 4, 6, 8, 10, 12, 14]

而对于reduce(function, sequence),其通过从调用sequence中的前两个元素开始,之后通过用function以这前两个元素为参数计算后的结果作为一个参数,并与第三个元素一起又作为两个function的参数,以此类推,最终返回一个值。例如计算从1-10的和,可以用如下的方式:

>>> def add(x,y): return x+y
...
>>> reduce(add, range(1, 11))
55

如果sequence中只有一个元素,那么就直接返回那个元素;如果sequence是空的,则会引起一个异常。并且对于reduce函数,其还可以有第三个参数,用来指明开始reduce的起始位置,这里就不举例了。需要说明的是,请不要使用这种reduce的方式来实现sum这个功能,Python中内建的sum(sequence)函数已经提供了这样的功能,这里只是用sum这样的功能来解释reduce的使用。

List解析

所谓List解析就是指,在创建List时,我们可以用表达式的方式来描述List的构成。举例如下:

>>>squares = [x**2 for x in range(10)]
>>>squares
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> [(x, y) for x in [1,2,3] for y in [3,1,4] if x != y]
[(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]

可以看到,在[]内我们首先定义了元素的类型,之后是通过for和if语句描述元素产生的规则。对于tuple类型的元素,必须要加上圆括弧。

这里再举一个例子,我们可以通过两个for语句,来解开一个嵌套的List:

>>> vec = [[1,2,3], [4,5,6], [7,8,9]]
>>> [num for elem in vec for num in elem]
[1, 2, 3, 4, 5, 6, 7, 8, 9]

关于tuple类型

tuple和list有很多相似的地方,但是需要注意的是,tuple的元素是不可变的,而list是可变的。tuple中有两种操作是非常有用的:打包(packing)和解包(unpacking)。举例如下:

>>> t = 12345, 54321, 'hello!'
>>> t[0]
12345
>>> t
(12345, 54321, 'hello!')
>>> x, y, z = t

前者将不同类型的元素打包成一个元组,而后者将t元组进行解包,将三个元素分别映射到x、y和z。

关于set类型

set表示集合,集合类型中的元素都是无序的,并且set类型中没有重复的元素。下面的代码片段很好地解释了set类型的特点及一些对其的操作:

>>> basket = ['apple', 'orange', 'apple', 'pear', 'orange', 'banana']
>>> fruit = set(basket)               # create a set without duplicates
>>> fruit
set(['orange', 'pear', 'apple', 'banana'])
>>> 'orange' in fruit                 # fast membership testing
True
>>> 'crabgrass' in fruit
False

>>> # Demonstrate set operations on unique letters from two words
...
>>> a = set('abracadabra')
>>> b = set('alacazam')
>>> a                                  # unique letters in a
set(['a', 'r', 'b', 'c', 'd'])
>>> a - b                              # letters in a but not in b
set(['r', 'd', 'b'])
>>> a | b                              # letters in either a or b
set(['a', 'c', 'r', 'd', 'b', 'm', 'z', 'l'])
>>> a & b                              # letters in both a and b
set(['a', 'c'])
>>> a ^ b                              # letters in a or b but not both
set(['r', 'd', 'b', 'm', 'z', 'l'])

和List一样,Python也可以对set类型进行解析来创建set:

>>> a = {x for x in 'abracadabra' if x not in 'abc'}
>>> a
set(['r', 'd'])

Dictionary类型

字典类型和其它语言中可能有的关联数组有关。用一句话来表示字典类型:字典类型就是一个无序的key : value结合,且在一个字典内key是唯一的。字典类型可以用大括号来创建,也可以与集合类型相似,用dict()函数来构造字典类型。举个例子来说明:

>>> 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']
>>> 'guido' in tel
True
>>> dict([('sape', 4139), ('guido', 4127), ('jack', 4098)])
{'sape': 4139, 'jack': 4098, 'guido': 4127}
>>> {x: x**2 for x in (2, 4, 6)}
{2: 4, 4: 16, 6: 36}
>>> dict(sape=4139, guido=4127, jack=4098)
{'sape': 4139, 'jack': 4098, 'guido': 4127}

可以看到,key()方法会返回字典中的所有key。并且在用dict()函数创建字典时,key和value的对应既可以用冒号也可以用等号。并且字典类型也同样支持解析。

循环遍历技巧

在遍历一个序列时,如果想同时获取序号和元素值,可以通过使用enumerate()函数:

>>> for i, v in enumerate(['tic', 'tac', 'toe']):
...     print i, v
...
0 tic
1 tac
2 toe

如果想安装字典序来遍历一个序列,可以通过sorted()函数来实现:

>>> basket = ['apple', 'orange', 'apple', 'pear', 'orange', 'banana']
>>> for f in sorted(set(basket)):
...     print f
...
apple
banana
orange
pear

遍历字典时,同时获取key和value的方法也非常简单,只需用到iteritems()方法:

>>> knights = {'gallahad': 'the pure', 'robin': 'the brave'}
>>> for k, v in knights.iteritems():
...     print k, v
...
gallahad the pure
robin the brave

有关条件(Condition)的更多说明

在if或while语句中,我们都会添加很多条件来表明某个语句块的执行与否。这里提一些关于比较条件的说明。

对于条件a < b == c,其表示的是判断a是否小于b,并且b是否等于c。并不是说用a < b的比较运算结果再和c进行比较。

请看下面这个例子:

>>> string1, string2, string3 = '', 'Trondheim', 'Hammer Dance'
>>> non_null = string1 or string2 or string3
>>> non_null
'Trondheim'

或许有的人看的这个代码,会认为non_null是不是应该被赋值成True了?不过,可以看到,由于string1为空字符串,所有or表达式需要继续向后看,string2不为空,由此该or表达式的值可以确定为真了,于是不再向后判断,直接就将string2的值赋给non_null,而并不是将true赋值给non_null。

这里还有一点需要说明,和C语言不同,Python的表达式中不允许进行赋值,你可能会对此充满怨言,但这也可以避免一个问题:不会像C语言那样出现将==写出=的情况。

结语

在官方文档中,本节的最后还介绍了有关不同类型间比较的问题,不过正像官方文档所说的那样,虽然不同类型的对象间可以比较,不过我们还是不应该依赖这个,因为在未来这个特性可能会发生改变,所以这里就不作详细介绍了。

你可能感兴趣的:(python,tutorial)