本文根据SO上的热门问答hidden features of python整理而成,早期有人做过类似的整理,但是内容比较旧而且比较粗糙,因此笔者在原文基础上加入自己的一些理解,另外那些高质量的评论也引入进来了。总之,这是一篇用心之作,希望你可以喜欢。
链式比较操作
1 2 3 4 5 6 7 8 9 10 11 |
>>> x = 5 >>> 1 < x < 10 True >>> 10 < x < 20 False >>> x < 10 < x*10 < 100 True >>> 10 > x <= 9 True >>> 5 == x > 4 True |
你可能认为它执行的过程先是:1 < x
,返回True
,然后再比较True < 10
,当然这么做也是返回True
,比较表达式True < 10
,因为解释器会把True
转换成1
,False
转换成0
。但这里的链式比较解释器在内部并不是这样干的,它会把这种链式的比较操作转换成:1 < x and x < 10
,不信你可以看看最后一个例子。这样的链式操作本可以值得所有编程语言拥有,但是很遗憾
枚举
1 2 3 4 5 6 7 8 9 |
>>> a = ['a', 'b', 'c', 'd', 'e'] >>> for index, item in enumerate(a): print index, item ... 0 a 1 b 2 c 3 d 4 e >>> |
用enumerate包装一个可迭代对象,可以同时使用迭代项和索引,如果你不这么干的话,下面有一种比较麻烦的方法:
1 2 |
for i in range(len(a)): print i, a[i] |
enumerate 还可以接收一个可选参数start,默认start等于0。enumerate(list, start=1)
,这样index的起始值就是1
生成器对象
1 2 3 |
x=(n for n in foo if bar(n)) #foo是可迭代对象 >>> type(x) <type 'generator'> |
你可以把生成器对象赋值给x,意味着可以对x进行迭代操作:
1 2 |
for n in x: pass |
它的好处就是不需要存储中间结果,也许你会使用(列表推倒式):
1 2 3 |
x = [n for n in foo if bar(n)] >>> type(x) <type 'list'> |
它比生成器对象能带来更快的速度。相对地,生成器更能节省内存开销,它的值是按需生成,不需要像列表推倒式一样把整个结果保存在内存中,同时它不能重新迭代,列表推倒式则不然。
iter()可接收callable参数
iter()内建函数接收的参数分为两种,第一种是:
1 |
iter(collection)---> iterator |
参数collection必须是可迭代对象或者是序列 ,第二种是:
用enumerate包装一个可迭代对象,可以同时使用迭代项和索引,如果你不这么干的话,下面有一种比较麻烦的方法:
1 2 |
for i in range(len(a)): print i, a[i] |
enumerate 还可以接收一个可选参数start,默认start等于0。enumerate(list, start=1)
,这样index的起始值就是1
生成器对象
1 2 3 |
x=(n for n in foo if bar(n)) #foo是可迭代对象 >>> type(x) <type 'generator'> |
你可以把生成器对象赋值给x,意味着可以对x进行迭代操作:
1 2 |
for n in x: pass |
它的好处就是不需要存储中间结果,也许你会使用(列表推倒式):
1 2 3 |
x = [n for n in foo if bar(n)] >>> type(x) <type 'list'> |
它比生成器对象能带来更快的速度。相对地,生成器更能节省内存开销,它的值是按需生成,不需要像列表推倒式一样把整个结果保存在内存中,同时它不能重新迭代,列表推倒式则不然。
iter()可接收callable参数
iter()内建函数接收的参数分为两种,第一种是:
1 |
iter(collection)---> iterator |
参数collection必须是可迭代对象或者是序列 ,第二种是:
1 |
iter(callable, sentinel) --> iterator |
callable函数会一直被调用,直到它的返回结果等于sentinel,例如:
1 2 3 4 |
def seek_next_line(f): #每次读一个字符,直到出现换行符就返回 for c in iter(lambda: f.read(1),'\n'): pass |
小心可变的默认参数
1 2 3 4 5 6 7 8 9 10 |
>>> def foo(x=[]): ... x.append(1) |