class: middle, inverse # Python 技巧 ``` _____ _ _ _ __ _ _ |_ _| __(_) ___| | _____ | '_ \| | | | | || '__| |/ __| |/ / __| | |_) | |_| | | || | | | (__| <\__ \ | .__/ \__, | |_||_| |_|\___|_|\_\___/ |_| |___/ ``` ### 不积跬步无以至千里 ##### Github地址:[https://github.com/vimiix/python_tricks](https://github.com/vimiix/python_tricks) ##### Slide链接:[http://vimiix.com/python_tricks](http://vimiix.com/python_tricks) ``` Vimiix 2017.12.20 ``` --- class: center, middle, inverse ## 人生苦短,我用Python ### Life is short, use Python. --- class: inverse ## 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. Flat is better than nested. Sparse is better than dense. Readability counts. Special cases aren't special enough to break the rules. Although practicality beats purity. Errors should never pass silently. Unless explicitly silenced. ... ''' ``` --- class: inverse ## 简单的服务器 #### 你如果想快速且简单地共享一个目录中的文件,你只需在终端执行下面对应版本的指令: ```python # Python2 python -m SimpleHTTPServer # Python 3 python3 -m http.server ``` --- class: inverse ## 将列表内的所有元素组合成一个字符串 ```python a = ["Vimiix", "is", "a", "Python", "Developer"] print(" ".join(a)) # Vimiix is a Python Developer ``` --- class: inverse ## 不用循环语句打印重复字符 ```python print("code"*4) # codecodecodecode ``` --- class: inverse ## 检查两个字符串是否包含相同个数的字符组成 ```python from collections import Counter def is_anagram(str1, str2): return Counter(str1) == Counter(str2) res = is_anagram('abcd', 'dbca') print(res) # True res = is_anagram('abcd', 'dbaa') print(res) # False ``` --- class: inverse ## 函数参数解包 ``` # Function argument unpacking def myfunc(x, y, z): print(x, y, z) tuple_vec = (1, 0, 1) dict_vec = {'x': 1, 'y': 0, 'z': 1} myfunc(*tuple_vec) # 1, 0, 1 myfunc(**dict_vec) # 1, 0, 1 ``` --- class: inverse ## 多种方法来验证多条件语句 ``` x, y, z = 0, 1, 0 if x == 1 or y == 1 or z == 1: print('passed') if 1 in (x, y, z): print('passed') # These only test for truthiness: if x or y or z: print('passed') if any((x, y, z)): print('passed') ``` --- class: inverse ## 使用timeit模块来测试函数执行效率 ``` import timeit rt = timeit.timeit('"-".join(str(n) for n in range(100))', number=10000) print(rt) # 0.252703905106 rt = timeit.timeit('"-".join([str(n) for n in range(100)])', number=10000) print(rt) # 0.234980106354 rt = timeit.timeit('"-".join(map(str, range(100)))', number=10000) print(rt) # 0.152318954468 ``` --- class: inverse ## 合并两个字典在不同版本中的写法 ``` x = {'a': 1, 'b': 2} y = {'b': 3, 'c': 4} # Python 3.5+ z = {**x, **y} print(z) # {'c': 4, 'a': 1, 'b': 3} # Python 2.x z = dict(x, **y) print(z) # {'a': 1, 'c': 4, 'b': 3} ``` --- class: inverse ## 巧用json模块更舒服的打印字典 ``` # 标准打印出来,对于阅读不是很友好 my_mapping = {'a': 23, 'b': 42, 'c': 0xc0ffee} print(my_mapping) # {'b': 42, 'c': 12648430. 'a': 23} # đ # 使用json可以更好的展示 import json print(json.dumps(my_mapping, indent=4, sort_keys=True)) # { # "a": 23, # "b": 42, # "c": 12648430 # } ``` --- class: inverse ## 通过字典的值(value)排序输出 ``` # How to sort a Python dict by value xs = {'a': 4, 'b': 3, 'c': 2, 'd': 1} print(sorted(xs.items(), key=lambda x: x[1])) # [('d', 1), ('c', 2), ('b', 3), ('a', 4)] # Or: import operator print(sorted(xs.items(), key=operator.itemgetter(1))) # [('d', 1), ('c', 2), ('b', 3), ('a', 4)] ``` --- class: inverse ## 字典的get用法和默认值 ``` name_for_userid = { 382: "Alice", 590: "Bob", 951: "Dilbert", } def greeting(userid): return "Hi %s!" % name_for_userid.get(userid, "there") print(greeting(382)) # "Hi Alice!" print(greeting(2333333)) # "Hi there!" ``` --- class: inverse ## 用namedtuple来代替简单的类 ``` from collections import namedtuple Car = namedtuple('Car', 'color mileage') # 实例化一个Car,并像类一样使用 my_car = Car('red', 3812.4) print(my_car.color) # 'red' print(my_car.mileage) # 3812.4 print(my_car) # Car(color='red' , mileage=3812.4) # 就像元组一样,namedtuple也不可更改: my_car.color = 'blue' # AttributeError: "can't set attribute" ``` --- class: inverse ## Bool值可以作为整型数值来使用 - True -> 1 - False -> 0 ### 这个用法比较含蓄 ``` num = 3 """算术运算""" print(isinstance(num, int) + (num < 10)) # 2 """作索引用""" print(['奇数', '偶数'][num % 2 == 0]) # 奇数 ``` --- class: inverse ## 列表逆序的几种方法 ``` """切片方式""" a = [5, 4, 3, 2, 1] print(a[::-1]) # [1, 2, 3, 4, 5] """列表内建函数,会改变数组本身""" a.reverse() print(a) # [1, 2, 3, 4, 5] a = [5, 4, 3, 2, 1] """函数方式, reversed()返回一个迭代器""" print([i for i in reversed(a)]) # [1, 2, 3, 4, 5] ``` --- class: inverse ## 用压缩器翻转字典键值 ``` d = {'a':1, 'b':2, 'c':3, 'd':4} print(d.items()) # [('a', 1), ('c', 3), ('b', 2), ('d', 4)] l = zip(d.values(), d.keys()) print(l) # [(1, 'a'), (3, 'c'), (2, 'b'), (4, 'd')] rd = dict(l) print(rd) # {1: 'a', 2: 'b', 3: 'c', 4: 'd'} ``` --- class: inverse ## 用字典推导式翻转字典键值 ``` d = {'a':1, 'b':2, 'c':3, 'd':4} print(d.items()) # [('a', 1), ('c', 3), ('b', 2), ('d', 4)] rd = {v:k for k,v in d.items()} print(rd) # {1: 'a', 2: 'b', 3: 'c', 4: 'd'} ``` --- class: inverse ## 判断一个数字是否为回文数 ```python def isPalindrome(self, x): """ 判断是否为回文数 :type x: int :rtype: bool """ if x < 0: return False return str(x)[::-1] == str(x) ``` --- class: inverse ## 矩阵转置 ```python mat = [[1, 2, 3], [4, 5, 6]] res = zip(*mat) print(res) # 注意:在py2中会直接输出下面的结果 # 在Py3中res是一个生成器,需求迭代输出结果。 # [(1, 4), (2, 5), (3, 6)] # for循环处理方法 res = [[mat[j][i] for j in range(len(mat))] \ for i in range(len(mat[0]))] ``` --- class: center, middle, inverse ## 持续更新中... --- class: middle, inverse ## 联系方式 ### - Website: http://vimiix.com - Twitter: http://twitter.com/_vimiix - GitHub: http://github.com/vimiix - Email: [i@vimiix.com](mailto:i@vimiix.com) --- class: center, middle, inverse ## 谢谢大家! ### 欢迎PR,欢迎扩散 --- class: center, middle, inverse Made in [Remark](http://remarkjs.com)