先不讲数据结构了,此次来讲说python中一些不被注意的功能。java
在python的设计哲学中,有这么一条内容:“Simple is better than complex”,简单的代码比复杂的要好,这也是为何python被推荐为初学者必学的语言。不少人初学python,每每会受到其余语言的影响,好比以前学过java的,把python代码写的像java同样。举个例子,在java中设计一个类时,咱们经常会为内部变量定义get和set方法,这是保证封装性的重要手段,可是在python中却不建议这样作,python中的内部变量使用单下划线表示(好比self.__name
),不过这样定义了仍是能够访问到私有变量。怎么说?python中使用约定,我不会强制说这个变量你不能访问,可是你最好不要这样作。若是须要对变量进行其余操做,使用@parameter装饰器进行get和set封装,这样直接访问内部变量会出错。讲偏了,关于类和对象这方面的内容之后再说。python
你若是打开python交互环境,输入import this
能够看到如下内容:正则表达式
The Zen of Python, by Tim Peters数据结构
Beautiful is better than ugly. 优美胜于丑陋机器学习
Explicit is better than implicit. 明了胜于晦涩函数
Simple is better than complex. 简单赛过复杂学习
Complex is better than complicated. 复杂赛过凌乱this
Flat is better than nested. 扁平胜于嵌套spa
Sparse is better than dense. 间隔胜于紧凑设计
......
这些是python的设计哲学,后面还有一些没列出来,在写python代码时最好听从这些设计哲学。
第一个功能。
若是让你写一段代码表示a大于2且小于10,大多数人都会用a > 2 && a < 10
对吧,在python中你能够直接使用2 < a < 10
。
a = 5 # 能够这样 print(2 < a < 10) # 也能够这样 print(10 > a <= 9)
True True
还有一个不少人可能都知道的技巧,就地交换值,而不须要中间变量。
a = 2 b = 3 print(a, b) # 直接交换 a, b = b, a print(a, b)
2 3 3 2
第二个功能。
咱们经常会须要用for循环来遍历序列中的值,而后进行某些操做。在其余语言中你可能这么写:
a = ['a', 'b', 'c', 'd', 'e'] for(int i = 0; i < len(a); i++): print(a[i])
在python中不少人会这么写,对a的长度使用range生成一个序列,而后遍历。
a = ['a', 'b', 'c', 'd', 'e'] # 对a的长度使用range生成一个序列,而后遍历 for i in range(len(a)): print(a[i])
a b c d e
其实你能够这样写,直接使用enumerate方法,它会返回序列的下标和值。
a = ['a', 'b', 'c', 'd', 'e'] # 对a的长度使用range生成一个序列,而后遍历 for i in enumerate(a): print(i) # 或者这样 for index, value in enumerate(a): print(index, value)
(0, 'a') (1, 'b') (2, 'c') (3, 'd') (4, 'e') 0 a 1 b 2 c 3 d 4 e
第三个功能。
通常状况下,循环语句和条件判断语句是互不相干的,if后面就是else,for以后是in。其实循环语句后面也能够跟着else。for以后跟着else的意思是,运行这个循环,而后执行else中的语句。
for i in foo: if i == 0: break else: print("i was never 0")
除了for循环后面能够跟着else,while和try/except以后也能够跟着else。
第四个功能。
用过字典的都知道,若是咱们须要字典中某个键的值,可使用d['key']
来获取,若是key不存在的话会抛出异常,这样确定很差了,若是使用d.get('key')
,在key值不存在时会默认返回None,这样就不用关心是否会有异常发生。其实还能够这样,d.get('key', 0)
,第二个参数指定key不存在时用来代替的值。
第五个功能。
正则表达式是个很让人头疼的东西,若是能加上注释该多好,这样我就知道本身写的是什么了。在Python中你能够这样。
# 对每个规则使用引号括起来 pattern = ( "^" # beginning of string "M{0,4}" # thousands - 0 to 4 M's "(CM|CD|D?C{0,3})" # hundreds - 900 (CM), 400 (CD), 0-300 (0 to 3 C's), # or 500-800 (D, followed by 0 to 3 C's) "(XC|XL|L?X{0,3})" # tens - 90 (XC), 40 (XL), 0-30 (0 to 3 X's), # or 50-80 (L, followed by 0 to 3 X's) "(IX|IV|V?I{0,3})" # ones - 9 (IX), 4 (IV), 0-3 (0 to 3 I's), # or 5-8 (V, followed by 0 to 3 I's) "$" # end of string ) print(pattern) # 而后bapattern放入对应的re匹配方法中。
^M{0,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})$
第六个功能。
在上一篇迭代器和生成器中说过,iter()函数能够生成一个迭代器,以后你就能使用循环或者next方法来产出值。其实iter还接受第二个参数,它的做用是在迭代的过程当中若是碰到第二个参数则中止。看个例子:
def seek_next_line(f): for c in iter(lambda: f.read(1),'\n'): pass
上面的代码中,从f中循环读入,若是碰到\n
则结束读取。
其余的技巧像使用生成器表达式,利用拆包方法等等,以前都有说过,这里再也不赘述。
本人才疏学浅,上文中不免有些错误,还请各位品评指正。若是以为写的还行,欢迎关注个人公众号MLGroup,带你走进机器学习的世界。