关于Python的那些“不为人知的”特性【1】

铁扇公主1 发布于 2017/06/18 15:06
阅读 160
收藏 1

链式比较操作

 

 

>>> 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,不信你可以看看最后一个例子。这样的链式操作本可以值得所有编程语言拥有,但是很遗憾,其他语言很少有这样的支持。

 

enumerate枚举

 

>>> 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包装一个可迭代对象,可以同时使用迭代项和索引,在迭代的同时获取迭代项所在位置时非常方便。如果你不这么干的话,下面有一种比较麻烦的方法:

 

for i in range(len(a)):
   print i, a[i]

 

enumerate 还可以接收一个可选参数start,默认start等于0。enumerate(list, start=1),这样index的起始值就是1

 

生成器对象

 

x=(n for n in foo if bar(n))  #foo是可迭代对象
>>> type(x)
<type 'generator'>

 

你可以把生成器对象赋值给x,意味着可以对x进行迭代操作:

for n in x:
   pass

 

它的好处就是不需要存储中间结果,也许你会使用(列表推导式):

 

x = [n for n in foo if bar(n)]
>>> type(x)
<type 'list'>

 

它比生成器对象能带来更快的速度。相对地,生成器更能节省内存开销,它的值是按需生成,不需要像列表推倒式一样把整个结果保存在内存中,同时它不能重新迭代,列表推导式则不然。

 

字典推导式

 

在Python2.6以下版本字典生成器可以接受迭代的键值对:

d = dict((key, value) for (key, value) in iterable)

 

从Python2.7或者Python3以后,你可以直接用字典推导式语法:

d = {key: value for (key, value) in iterable}

 

你也可以用任何方式的迭代器(元组,列表,生成器..),只要可迭代对象的元素中有两个值,

d = {value: foo(value) for value in sequence if bar(value)}

 

更为高级的用法:

 

def key_value_gen(k):
  yield chr(k+65)
  yield chr((k+13)%26+65)
d = dict(map(key_value_gen, range(26)))

 

iter()可接收callable参数

 

iter()内建函数接收的参数分为两种,第一种是:

iter(collection)---> iterator

 

参数collection必须是可迭代对象或者是序列 ,第二种是:

iter(callable, sentinel) --> iterator

 

callable函数会一直被调用,直到它的返回结果等于sentinel,例如:

def seek_next_line(f):


   #每次读一个字符,直到出现换行符就返回
   for c in iter(lambda: f.read(1),'\n'):  
       pass

 

小心可变的默认参数

 

>>> def foo(x=[]):
...     x.append(1)
...     print x
... 
>>> foo()
[1]
>>> foo()
[1, 1]
>>> foo()
[1, 1, 1]

 

取而代之的是你应该使用一个标记值表示“没有指定”来替换可变对象,如:

 

>>> def foo(x=None):
...     if x is None:
...         x = []
...     x.append(1)
...     print x
>>> foo()
[1]
>>> foo()
[1]

 

发送值到生成器函数在中

 

def mygen():
   """Yield 5 until something else is passed back via send()"""
   a = 5
   while True:
       f = (yield a) #yield a and possibly get f in return
       if f is not None: 
           a = f  #store the new value

 

你可以:

 

>>> g = mygen()
>>> g.next()
5
>>> g.next()
5
>>> g.send(7)  #we send this back to the generator
7
>>> g.next() #now it will yield 7 until we send something else
7

 

如果你不喜欢使用空格缩进,那么可以使用C语言花括号{}定义函数:

 

>>> from __future__ import braces   #这里的braces 指的是:curly braces(花括号)
 File "<stdin>", line 1
SyntaxError: not a chance

 

当然这仅仅是一个玩笑,想用花括号定义函数?没门。感兴趣的还可以了解下:

from __future__ import barry_as_FLUFL

 


学习是对自己最好的投资,而机会属于有准备的人,这是一个看脸的时代,但最终拼的是实力。人和人之间的差距不在于智商,而在于如何利用业余时间,所以没有等出来的辉煌,只有干出来的精彩。其实只要你想学习,什么时候开始都不晚,不要担心这担心那,你只需努力,剩下的交给时间,而你之所以还没有变强,只因你还不够努力,要记得付出不亚于任何人的努力。


你的想法再精彩,那是想法的价值
而你的价值,永远体现在行动之中
如果还停留在想的价值中,请赶快行动,
如果你学习还停止在原处,请咨询我帮助你开始
 

加载中
返回顶部
顶部