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