第一行
Python3 开头的一行到底应该怎么写?
查阅 Google 的代码仓库,找到若干以 Python3 为主的 repo,选择比较流行的库 Trax 作为范本。随机抽取某个脚本(https://github.com/google/trax/blob/master/trax/trainer.py),该脚本的头部如下所示:
# coding=utf-8
所以今后 python3 文件的开头都将参照该规范。
标准的函数声明
LeetCode 的 Python3 模板具有较好的编码规范,如下所示是一个编码风格良好的函数声明:
class Solution:
def shortestSubarray(self, A: List[int], K: int) -> int:
pass
该函数接收两个参数,参数的类型分别为 List[int] 和 int,函数的返回值为 int
ref:https://leetcode-cn.com/problems/shortest-subarray-with-sum-at-least-k/
构造HTTP请求
def get_html(url):
headers = {
'User-Agent': r'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko)'
r'Chrome/45.0.2454.85 Safari/537.36 115Browser/6.0.3',
'Connection': 'keep-alive'
}
req = request.Request(url, headers=headers)
page = request.urlopen(req).read()
page = page.decode('utf-8')
return page
字符串前缀的语义
f-string
f-string 是 python3.6 之后版本添加的,称之为字面量格式化字符串,是新的格式化字符串的语法。
之前我们习惯用百分号 (%):
>>> name = 'Runoob'
>>> 'Hello %s' % name
'Hello Runoob'
f-string 格式话字符串以 f 开头,后面跟着字符串,字符串中的表达式用大括号 {} 包起来,它会将变量或表达式计算后的值替换进去,实例如下:
>>> name = 'Runoob'
>>> f'Hello {name}' # 替换变量
>>> f'{1+2}' # 使用表达式
'3'
>>> w = {'name': 'Runoob', 'url': 'baidu.com'}
>>> f'{w["name"]}: {w["url"]}'
'Runoob: baidu.com'
u-string
在Python2中,普通字符串是以8位ASCII码进行存储的,而Unicode字符串则存储为16位unicode字符串,这样能够表示更多的字符集。使用的语法是在字符串前面加上前缀 u。
在Python3中,所有的字符串都是Unicode字符串。所以在python3中,下面的两个字符串等价:
>>> a = 'abc'
>>> b = u'abc'
>>> a is b
True
b-string
在 python3 中,字符串前缀 b 意味着将字符串存储为 ASCII 码,无法存储中文。每个字符由底层中的一个字节(8位)来表示。
r-string
在 python3 中,字符串前缀 r 意味着将字符串中的所有字符都视为普通字符,所以主要解决的是转义字符的和特殊字符的问题。
matplotlib
折线图
from matplotlib import pyplot as plt
plt.title("Matplotlib demo")
plt.xlabel("x axis caption")
plt.ylabel("y axis caption")
plt.plot(x, y)
plt.show()
logging
python3 内置日志函数包
import logging
logging.basicConfig(
format='%(asctime)s - %(levelname)s - %(name)s - %(message)s',
datefmt='%m/%d/%Y %H:%M:%S',
filemode='w',
level=logging.INFO)
logger = logging.getLogger(__name__)
logger.info("[content]%s" % (html))
argparse
首先,需要导入 argparse 库,并且声明一个参数解析器。
import argparse
parser = argparse.ArgumentParser()
其次,参数分为两种,一种是位置参数,一种是可选参数。位置参数是运行程序的必填项。
# Positional arguments
parser.add_argument("train", type=str,
help="training data path, i.e. ctb8 and 1998")
parser.add_argument("embedding", type=str,
help="word embedding path")
第二种是可选参数,区别在于加入了“--”前缀。
# Optional arguments
parser.add_argument("--sep", default=0, type=int,
help="the separators of training data, split token and label, 0 for _(default), 1 for /")
parser.add_argument("-ml", "--max_len", default=50, type=int,
help="length of training data sequence, default is 50")
parser.add_argument("-e", "--epochs", default=3, type=int)
args = parser.parse_args()
最后,获得用户的输入很简单,如下所示。
seperator = '_' if args.sep is 0 else '/'
Ref: https://docs.python.org/3.7/howto/argparse.html
numpy
pad
import numpy as np
x = np.random.normal(size=(2,2))
np.pad(x, ((0,1), (1,0)), 'constant')
在填充(pad)前,x 的值如下所示:
array([[-1.04965022, 1.50657074],
[-0.95876126, -0.46918995]])
填充后,x 的值如下所示:
array([[ 0. , -1.04965022, 1.50657074],
[ 0. , -0.95876126, -0.46918995],
[ 0. , 0. , 0. ]])
pad 有三个参数:
- 待填充的 numpy ndarray
- 每个维度上 before 和 after 的填充数量
- 填充值
第二个参数需要着重介绍。array_like,每个 tuple 表达了在该维度上的 before 填充数和 after 填充数。
(
(上, 下), # 第一个维度
(左, 右), # 第二个维度
......
)
os
walk
os.walk 函数可以遍历指定路径
import os
# root: os.walk 函数第一个参数 path 的延续
# dirs: 当前目录下的文件夹
# files:当前目录下的文件
for root, dirs, files in os.walk(path, topdown=False):
for name in files:
print(os.path.join(root, name))
for name in dirs:
print(os.path.join(root, name))
json
读取json
import json
with open(fname, encoding='utf-8') as f:
data = json.load(f)
print(data)
封装json
string
find
Python3中的字符串查找函数的底层算法采用了 Boyer–Moore–Horspool 算法。不仅是 find 函数,其实 index, split, replace, __contains__, 和 SRE prefix scanner 也采用了 Boyer–Moore–Horspool 算法。
s = "Hello World!"
s.find("World")
算法:Boyer–Moore–Horspool
时间复杂度:平均O(n),最坏O(kn),其中k是模式的长度,n是字符串长度。
算法:Knuth–Morris–Pratt
时间复杂度:平均O(n+k),最坏O(kn),其中k是模式的长度,n是字符串长度。
Reference:
[1] https://en.wikipedia.org/wiki/Boyer–Moore–Horspool_algorithm
[2] https://github.com/python/cpython/blob/master/Objects/stringlib/fastsearch.h#L5
[3] http://effbot.org/zone/stringlib.htm
[4] https://stackoverflow.com/questions/681649/how-is-string-find-implemented-in-cpython
[5] https://en.wikipedia.org/wiki/Knuth–Morris–Pratt_algorithm