python - python中隐藏的功能
你如果打开python交互环境,输入import this可以看到以下内容:
1
2
3
4
5
6
7
|
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. 复杂胜过凌乱 Flat is better than nested. 扁平胜于嵌套 Sparse is better than dense. 间隔胜于紧凑 |
在写python代码时最好遵从这些设计哲学。
第一个功能。
如果让你写一段代码表示a大于2且小于10,大多数人都会用a > 2 && a < 10对吧,在python中你可以直接使用2 < a < 10。
1
2
3
4
5
|
a = 5 # 可以这样 print(2 < a < 10)
# 也可以这样 print(10 > a <= 9) |
1
2
|
True True |
还有一个很多人可能都知道的技巧,就地交换值,而不需要中间变量。
1
2
3
4
5
6
|
a = 2 b = 3 print(a, b) # 直接交换 a, b = b, a print(a, b) |
1
2
|
2 3 3 2 |
第二个功能。
我们常常会需要用for循环来遍历序列中的值,然后进行某些操作。在其他语言中你可能这么写:
1
2
3
|
a = ['a', 'b', 'c', 'd', 'e'] for(int i = 0; i < len(a); i++): print(a[i]) |
在python中很多人会这么写,对a的长度使用range生成一个序列,然后遍历。
1
2
3
4
|
a = ['a', 'b', 'c', 'd', 'e'] # 对a的长度使用range生成一个序列,然后遍历 for i in range(len(a)): print(a[i]) |
1
2
3
4
5
|
a b c d e |
其实你可以这样写,直接使用enumerate方法,它会返回序列的下标和值。
1
2
3
4
5
6
7
|
a = ['a', 'b', 'c', 'd', 'e'] # 对a的长度使用range生成一个序列,然后遍历 for i in enumerate(a): print(i) # 或者这样 for index, value in enumerate(a): print(index, value) |
1
2
3
4
5
6
7
8
9
10
|
(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中的语句。
1
2
3
4
5
|
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中你可以这样。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
# 对每一个规则使用引号括起来 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匹配方法中。 |
1 |
^M{0,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})$ |
第六个功能。
在上一篇迭代器和生成器中说过,iter()函数可以生成一个迭代器,之后你就能使用循环或者next方法来产出值。其实iter还接受第二个参数,它的作用是在迭代的过程中如果碰到第二个参数则停止。看个例子:
1
2
3
|
def seek_next_line(f): for c in iter(lambda: f.read(1),'\n'): pass |
上面的代码中,从f中循环读入,如果碰到\n则结束读取。