Python技巧篇(1):内置对象及函数
Python作为一种高效的脚本语言,内置了很多实用的函数,同时也提供了丰富的工具模块,所有的这些使得Python用起来得心应手!
下面是我总结的几种内置对象及函数的应用技巧,当然还有很多我并不知道的技巧,望与广大的 Python fans 交流学习。
1、强大的列表解析功能
- 对列表元素的简单操作:例如将列表的每个元素乘以2
list1 = [1,2,3,4] list1 = [x*2 for x in list1] #[2,4,6,8]
- 对文件的操作:例如只收集文件中以'p'开头的行
lines = [line.rstrip() for line in open('filename') if line[0] == 'p']
- 对两个集合进行排列组合:例如对'abc'与'lmn'进行排列组合
str1 = 'abc' str2 = 'lmn' [x+y for x in str1 for y in str2] #['al', 'am', 'an', 'bl', 'bm', 'bn', 'cl', 'cm', 'cn']
- 对字符串的操作
#索引操作 s = 'spam' s[0] # 's' s[-1] # 'm' #分片操作 s[1:3] # 'pa' s[1:] # 'pam' s[:-1] # 'spa' s[:] # 'spam' s[::2] # 'sa' s[1::2] # 'pm' s[::-1] # 'maps' s[-1:0:-1] # 'map'
- 对列表的操作
#索引操作 list1 = ['spam','SPAM','Spam'] list1[0] # 'spam' list1[-1] # 'Spam' #分片操作 list1[1:2] # ['SPAM'] list1[1:] # ['SPAM', 'Spam'] list1[:-1] # ['spam', 'SPAM'] list1[:] # ['spam', 'SPAM', 'Spam'] list1[::2] # ['spam', 'Spam'] list1[1::2] # ['SPAM'] list1[::-1] # ['Spam', 'SPAM', 'spam'] list1[-1:0:-1] # ['Spam', 'SPAM']
a='123' type(a) # <type 'str'> type(eval(a)) # <type 'int'>4、zip函数
- 内置的zip函数使用for循环实现并行遍历。在基本运算中,zip会取得一个或多个序列为参数,然后返回元组的列表,将这些序列中的并排的元素配成对。
>>> l1 = [1,2,3,4] >>> l2 = [5,6,7,8] >>> zip(l1,l2) [(1, 5), (2, 6), (3, 7), (4, 8)]
- 如果与 for 循环搭配,zip就会支持并行迭代
>>> for (x,y) in zip(l1,l2): ... print x, y, '--', x+y ... 1 5 -- 6 2 6 -- 8 3 7 -- 10 4 8 -- 12
- 在运行时构造字典
>>> keys = ['a', 'b', 'A', 'B'] >>> values = [96, 97, 65, 66] >>> d = dict(zip(keys, values)) >>> d {'a': 96, 'A': 65, 'B': 66, 'b': 97}
>>> def maker(n): ... def action(x): ... return x ** n ... return action ... >>> f=maker(2) >>> type(f) <type 'function'> >>> f(3) 9 >>> f(4) 166、匿名函数:lambda 除了def语句之外,Python还提供了一种生成函数对象的表达式形式。由于它于LISP语言中的一个工具很相似,所以称为lambda。就像def一样,这个表达式创建了一个之后能够调用的函数,但是它返回了一个函数而不是将这个函数赋值给一个变量名。这也就是lambda有时被称作匿名函数的原因了。
- lambda通常用来编写跳转表(jump table),也就是行为的列表或字典,能够按照需要执行相应的动作
- 行为列表示例:
>>> L = [(lambda x: x **2),(lambda x: x**3),(lambda x: x**4)] >>> for f in L: ... print f(2) ... 4 8 16
- 行为字典示例:
>>> key = 'got' >>> {'already':(lambda: 2+2),'got':(lambda: 2*4),'one':(lambda: 2**6)}[key]() 8
这样一个字典也就变成了一个多路分支的工具了
- 行为列表示例:
- lambda 与 if/else三元表达式的结合
>>> lower = lambda x,y: x if x < y else y >>> lower('a','b') 'a' >>> lower('b','a') 'a'
- 如果要在lambda函数中执行循环,能够嵌入map调用或列表解析表达式
- 嵌入map的示例
>>> import sys >>> showall = lambda x: map(sys.stdout.write,x) >>> t = showall(['spam\n','toast\n','eggs\n']) spam toast eggs >>> L = [1,2,3,4] >>> map((lambda x: x+3),L) [4, 5, 6, 7]
- 嵌入列表解析的示例
>>> showall = lambda x: [sys.stdout.write(line) for line in x] >>> t = showall(('bright\n','side\n','of\n','life\n')) bright side of life
- 嵌入map的示例
- 嵌套作用域和lambda
def func(): x = 4 action = (lambda n: x ** n) return action f = func() print f(2) #16, 4**2
- 概念 不像一般的函数会生成值后退出,生成器函数在生成值后自动挂起并暂停它们的执行和状态。正是因为这一点,无论是在从头计算整个序列的值,或者手动保存和恢 复类中的状态时,它们都常常作为一种使用的替代解决方案。生成器在被挂起时自动地保存状态,它的本地变量将保存状态信息,这些信息在函数恢复时将再度有 效。
- 生成器函数和一般函数的区别: 它们之间最大的区别就是生成器yield一个值,而不是return一个值。yield语句会将函数挂起,并向它的调用者返回一个值,但是保存足够的状态信息为了让其能够在函数从它挂起的地方恢复。这能够允许这些函数不断地产生一系列的值,而不是一次计算所有的值,之后将值以类似列表之类的形式来返回。
- 生成器函数在Python中与迭代器协议的概念联系在一起 包含了yield语句的函数将会特地编译为生成器。当调用是,它们返回了一个生成器对象,这个生成器对象支持迭代器对象接口。生成器函数也许有一个return语句,这个语句就是用来终止产生值的。
- 示例:
>>> def gensquares(n): ... for i in range(n): ... yield i ** 2 ... >>> type(gensquares(5)) <type 'generator'> >>> for i in gensquares(5): ... print i,',', ... 0 , 1 , 4 , 9 , 16 ,
- 生成器表达式:
生成器表达式就像一般的列表解析一样,但是它们是括在圆括号中而不是方括号中的。生成器表达式返回一个生成器对象。
>>> for x in (x ** 2 for x in range(4)): ... print x, ... 0 1 4 9>>> for x in (x ** 2 for x in range(4)): ... print x, ... 0 1 4 9
注意:如果生成器表达式是在其他括号之内的话,就像在那些函数调用之中,生成器自身的括号就不是必须的了。尽管这样,在下面第二个sorted调用中,还是需要额外的括号。>>> sum(x ** 2 for x in range(4)) 14 >>> sorted(x ** 2 for x in range(4)) [0, 1, 4, 9] >>> sorted((x ** 2 for x in range(4)), reverse=True) [9, 4, 1, 0] >>> import math >>> map(math.sqrt, (x ** 2 for x in range(4))) [0.0, 1.0, 2.0, 3.0]