Python3的书写技巧和应用

地道的循环

1
2
for i, name in enumerate(names):
print(i, name)

直接交换2个数字的位置

1
2
x, y = y, x
print(x, y)

链接比较操作符

1
2
3
4
5
6
7
8
n = 10
result = 1 < n < 20
print(result)
>>> True

result = 11 > n < 20
print(result)
>>> True

使用三元操作符进行条件赋值

1
2
3
4
5
6
7
#三元操作符是 if-else 语句(也就是条件操作符)的快捷操作
#[on_true] if [expression] else [on_false]
x = 10 if (y == 9) else 20


#同样,我们对类对象也可以这样操作:
x = (classA if y == 1 else classB)(param1, param2)

将一个列表的元素保存到新变量中

1
2
3
4
testList = [1,2,3]
x, y, z = testList
print(x, y, z)
>>> 1 2 3

打印出导入的模块的文件路径

1
2
3
4
5
6
import threading
import socket
print(threading)
print(socket)
>>> <module 'threading' from '/usr/lib/python3.7/threading.py'>
>>> <module 'socket' from '/usr/lib/python3.7/socket.py'>

使用交互式“_”操作符

1
2
3
4
5
6
7
8
#在 Python3 控制台中,每当我们测试一个表达式或调用一个函数时,结果都会分配一个临时名称,_(一条下划线)
#这里的"_"是上一个执行的表达式的结果。
>>> 2 + 1
3
>>> _
3
>>> print(_)
3

字典/集合推导

1
2
3
4
5
6
7
testDict = {i: i * i for i in range(10)}
testSet = {i * 2 for i in range(10)}
print(testDict)
print(testSet)

>>> {0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81}
>>> {0, 2, 4, 6, 8, 10, 12, 14, 16, 18}

调试脚本

1
2
3
#<pdb> 模块在 Python3 脚本中设置断点
import pdb
pdb.set_trace()

设置文件分享

1
2
#启用http服务器并设置端口为8000
$ python -m http.server 8000

在Python中检查对象

1
2
3
4
5
6
7
8
9
10
11
#我们可以通过调用 dir() 方法在 Python 中检查对象
test = [1, 3, 5, 7]
print( dir(test) )
>>> ['__add__', '__class__', '__contains__',
'__delattr__', '__delitem__', '__delslice__', '__doc__',
'__eq__', '__format__', '__ge__','__getattribute__', '__getitem__', '__getslice__',
'__gt__', '__hash__', '__iadd__', '__imul__','__init__', '__iter__', '__le__', '__len__',
'__lt__', '__mul__', '__ne__', '__new__', '__reduce__',
'__reduce_ex__', '__repr__','__reversed__', '__rmul__', '__setattr__', '__setitem__',
'__setslice__', '__sizeof__', '__str__','__subclasshook__', 'append', 'count', 'extend',
'index', 'insert', 'pop', 'remove', 'reverse', 'sort']

简化if语句

1
2
3
4
5
#验证多个值
if m in [1,3,5,7]:

#也可以用字符串
if m in '{1,3,5,7}'

在运行时检测Python的版本

1
2
3
4
5
import sys
if not sys.version_info >= (3,5):
print("Sorry, you aren't running on Python 3.5 or late\n")
print("Please upgrade to 3.5 or late.\n")
sys.exit(1)

组合多个字符串

1
2
test = ['I', 'Like', 'Python', 'automation']
print(" ".join(test))

翻转字符串/列表的3种方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
testList = [1, 3, 5]
testList.reverse()
print(testList)
>>> [5, 3, 1]

#在循环中迭代时翻转
for element in reversed([1,3,5]):
print(element)
>>> 5
>>> 3
>>> 1

#用切片翻转一个列表
"Test Python"[::-1]
>>> 'nohtyP tseT'

[1, 3, 5][::-1]
>>> [5, 3, 1]

使用枚举

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#使用枚举可以很容易地在循环中找到索引
testlist = [10, 20, 30]
for i, value in enumerate(testlist):
print(i, ':', value)
>>> 0 : 10
>>> 1 : 20
>>> 2 : 30

#在 Python3 中使用枚举量
#我们可以用如下方法来创建枚举定义
class Shapes:
Circle, Square, Triangle, Quadrangle = range(4)
print(Shapes.Circle)
>>> 0
print(Shapes.Square)
>>> 1
print(Shapes.Triangle)
>>> 2
print(Shapes.Quadrangle)
>>> 3

从函数中返回多个值

1
2
3
4
5
def x():
return 1, 2, 3, 4
a, b, c, d = x()
print(a, b, c, d)
>>> 1 2 3 4

使用*运算符解压缩函数参数

1
2
3
4
5
6
7
8
9
10
def test(x, y, z):
print(x, y, z)
testDict = {'x': 1, 'y': 2, 'z': 3}
testList = [10, 20, 30]
test(*testDict)
>>> x y z
test(**testDict)
>>> 1 2 3
test(*testList)
>>> 10 20 30

使用字典来存储表达式

1
2
3
4
5
6
7
8
stdcalc = {
'sum': lambda x, y: x + y,
'subtract': lambda x, y: x - y
}
print(stdcalc['sum'](9,3))
>>> 12
print(stdcalc['subtract'](9,3))
>>> 6

一行代码计算任何数字的阶乘

1
2
3
4
import functools
result = (lambda k: functools.reduce(int.__mul__, range(1,k+1),1))(3)
print(result)
>>> 6

找到一个列表中的出现最频繁的值

1
2
3
test = [1,2,3,4,2,2,3,1,4,4,4]
print(max(set(test), key=test.count))
>>> 4

重置递归限制

1
2
3
4
5
6
7
8
#Python3 将递归限制到 1000,我们可以重置这个值
import sys
x=1001
print(sys.getrecursionlimit())
>>> 1000
sys.setrecursionlimit(x)
print(sys.getrecursionlimit())
>>> 1001

检查一个对象的内存使用

1
2
3
4
import sys
x=1
print(sys.getsizeof(x))
>>> 14

使用 <slots> 减少内存消耗

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import sys
class FileSystem1(object):
def __init__(self, files, folders, devices):
self.files = files
self.folders = folders
self.devices = devices
print(sys.getsizeof(FileSystem1))
>>> 536

class FileSystem2(object):
__slots__ = ['files', 'folders', 'devices']
def __init__(self, files, folders, devices):
self.files = files
self.folders = folders
self.devices = devices
print(sys.getsizeof(FileSystem2))
>>> 448

使用lambda来模仿输出方法

1
2
3
4
import sys
lprint=lambda *args:sys.stdout.write(" ".join(map(str,args)))
lprint("python", "tips",1000,1001)
>>> python tips 1000 1001

从两个相关序列中创建一个字典

1
2
3
4
t1 = (1, 2, 3)
t2 = (10, 20, 30)
print(dict (zip(t1,t2)))
>>> {1: 10, 2: 20, 3: 30}

用一行代码搜索字符串的前后缀

1
2
3
4
print("http://www.google.com".startswith(("http://", "https://")))
>>> True
print("http://www.google.co.uk".endswith((".com", ".co.uk")))
>>> True

不使用任何循环,构造一个列表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import itertools
test = [[-1, -2], [30, 40], [25, 35]]
print(list(itertools.chain.from_iterable(test)))
>>> [-1, -2, 30, 40, 25, 35]

# 如果输入列表中有嵌入的列表或元组作为元素,那么就使用下面这种方法,不过也有个局限,它使用了 for 循环
def unifylist(l_input, l_target):
for it in l_input:
if isinstance(it, list):
unifylist(it, l_target)
elif isinstance(it, tuple):
unifylist(list(it), l_target)
else:
l_target.append(it)
return l_target
test = [[-1, -2], [1,2,3, [4,(5,[6,7])]], (30, 40), [25, 35]]
print(unifylist(test,[]))
>>> [-1, -2, 1, 2, 3, 4, 5, 6, 7, 30, 40, 25, 35]

使用字典实现switch_case

1
2
3
4
5
6
7
8
9

def python_switch(x=None):
case_dict = {'files': 10, 'folders': 5, 'devices': 2, None : None}
return case_dict[x]

print(python_switch('files'))
>>> 10
print(python_switch())
>>> None