基础篇
数据类型
1.dict
(1)交换字典的键和值
{value:key for key, value in a_dict.items()}
dict(zip(a_dict.values(), a_dict.keys()))
(2)dict合并
两个不同键值的dict合并
d3.update(d1)
d3.update(d2)
d3 = {**d1, **d2}
注意:如果两个dict有重复键值,那么以后update的dict的值为准。
(3)排序
(4)两个list
←
→
\leftarrow \rightarrow
←→ dict
dictionary = dict(zip(keys, values))
原理:
zip()接受多个iterable,并且返回一个iterator,每次调用next时返回一个元组,元组元素是传入的各个iterable中对应的元素。
但是这里keys, values的元素不能是iterable。
keys, values = zip(*dict)
- list
(1)将list合并为字符串
str.join(sequence) # 其中,str为分隔字符,sequence为待连接的元素序列,返回值为通过指定字符连接序列中的元素后生成的新字符串
例:
>>> str = ' '
>>> seq = ['There','is','a','book']
>>> print str.join(seq)
>>> There is a book # 输出结果
(2)合并
- l1+l2
并不影响l1和l2的值
返回l1和l2两个列表元素合并成为的列表
例:
l1 = [1, 2]
l2 = [3, 4]
print(l1+l2) # [1, 2, 3, 4]
- l1.append(l2)
在l1本地更改
将l2列表作为一个元素添加到l1列表尾
例:
l1 = [1, 2]
l2 = [3, 4]
print(l1.append(l2)) # None
print(l1) # [1, 2, [3, 4]]
- l1.extend(l2)
在l1本地更改
将l2列表每个元素添加到l1列表尾
例:
l1 = [1, 2]
l2 = [3, 4]
print(l1.expend(l2)) # None
print(l1) # [1, 2, 3, 4]
(3)删除元素
- remove: 删除单个元素,删除首个符合条件的元素,按值删除
- pop: 删除单个或多个元素,按位删除(根据索引删除)
- del:它是根据索引(元素所在位置)来删除
(4)查找元素
p=list.index(value)
注意,如果不存在value会报错
(5)排序
- 基础
sorted(iterable, key=None, reverse=False)
# sorted() 产生一个新的list,不改变list的值。sorted()可以对iterable对象排序
iterable.sort(key=None, reverse=False)
# sort() 对list本身进行排序,改变list的值。sort()只能对list排序。
# iterable为可迭代类型
# key 一般为列表元素的某个已命名的属性或函数。通常使用lambda表达式。
# reverse默认值为False,此时sorted()按从小到大的顺序排序。当reverse=True时,按照从大到小的顺序排序。
# key,reverse为可选参数
# 如果想要按照python2的方法写cmp函数自定义排序方法,可以:
from functools import cmp_to_key
lst.sort(key=cmp_to_key(cmp))
- 多个list按照一个list的排序顺序排序
t = tuple/list(zip(l1, l2, ...))
t = sorted(t, key=...)
l1, l2, ... = zip(*t) # 此时l的类型为tuple
l1 = list(l1)
l2 = list(l2)
函数篇
函数参数
函数参数:必选参数、默认参数、可选参数、关键字参数
- 必选参数
- 默认参数
即类似 power(x, n=2),其中n为默认参数
放在必选参数之后,可以进一步简化函数;
默认参数必须指向不变对象,若是指向可变对象,那么参数的地址已经确定,对于参数进行修改只是对该地址上的变量进行修改。 - 可变参数
即类似calc(* nums),其中nums为可变参数,函数内部接受得到的为一个tuple。
可变参数传入参数的个数是可变的,可以为[0, +)
传入的时候可以是*list/tuple,也可以是多个参数。 - 关键字参数
即类似person(name, ** kw),其中kw为关键字参数,函数内部接受得到的为一个dict。
传入的时候可以是**dict,也可以是多个含参数名的参数。
lambda函数
Python中,lambda函数也叫匿名函数,及即没有具体名称的函数,它允许快速定义单行函数,类似于C语言的宏,可以用在任何需要函数的地方。
-
lambda语法格式:
lambda 变量 : 要执行的语句
lambda [arg1 [, agr2,…argn]] : expression
其中[arg1 [, agr2,…argn]]为入口参数,expression为函数体。
lambda表达式会返回一个函数对象,如果没有变量接受这个返回值的话,它很快就会被丢弃。
例子:
g = lambda x : x ** 2
g(3) # 9 -
lambda表达式特殊应用
由于lambda只是一个表达式,所以它可以直接作为list和dict的成员 -
lambda函数的应用结果
(1) lambda的使用大量简化了代码,使代码简练清晰
(2) lambda 并不会带来程序运行效率的提高
(3) lambda会在一定程度上降低代码的可读性,如果不是非常熟悉python的人或许会对此感到不可理解
总结:lambda 是为了减少单行函数的定义而存在的。
模块篇
OS
OS常用的文件/目录方法
os.chdir(path) // change current work dir
os.getcwd() // return current work dir
os.listdir(path) // return files/sub work dirs in the path
os.remove(path) // remove file
os.removedirs(path) // remove dirs
os.rmdir(path) // remove empty dir
os.path模块
os.path.dirname(path) // 返回文件路径
os.path.isabs/isfile/isdir/islink(path)
os.path.join(path1[, path2[, …]]) // 合并文件和目录名成为一个路径
os.path.split(path) // 将文件名和路径分开
tqdm
自定义进度条显示信息
from tqdm import trange
from random import random,randint
import time
import tqdm
bar = tqdm.tqdm(range(10))
#设置进度条左边显示的信息
tqdm.tqdm.set_description(bar, desc="GEN %i"%i)
#设置进度条右边显示的信息
t.set_postfix(loss=random(),gen=randint(1,999),str="h",lst=[1,2])
pdb
pdb为Python程序定义了一个交互式源代码调试器。它支持在源行级别设置(条件)断点和单步执行,检查堆栈框架,源代码列表以及在任何堆栈框架的上下文中评估任意Python代码。它还支持事后调试,可以在程序控制下调用。
- pdb启动方式
(1)非侵入式方法(不用额外修改源代码,在命令行下直接运行就能调试)
python3 -m pdb filename.py
(2)侵入式方法(需要在被调试的代码中添加一行代码然后再正常运行代码)
import pdb;pdb.set_trace()
运行代码,程序会自动在pdb.set_trace()暂停并进入pdb调试环境;相当于添加了断点。
成功启动的标志如下:
(Pdb)
然后就可以开始输入pdb命令了。 - pdb命令
(1)查看源代码
命令:l
说明:查看当前位置前后11行源代码(多次会翻页),当前位置在代码中会用–>这个符号标出来;
命令:ll
说明:查看当前函数或框架的所有源代码
(2)添加断点
命令:
b
b line_id
b file_name:line_id
b function_name
参数:
file_name 文件名,断点添加到哪个文件,如test.py
line_id 表示断点添加到的行数
function_name 函数名,在该函数执行的第一行设置断点
说明:
1.不带参数表示查看断点设置
2.带参则在指定位置设置一个断点
(3)添加临时断点
命令:
tbreak
tbreak lineno
tbreak filename:lineno
tbreak functionname
参数:同b
说明:执行一次后时自动删除(这就是它被称为临时断点的原因)
(4)清除断点
命令:
cl
cl filename:lineno
cl bpnumber [bpnumber …]
参数:bpnumber 断点序号(多个以空格分隔)
说明:
1.不带参数用于清除所有断点,会提示确认(包括临时断点)
2.带参数则清除指定文件行或当前文件指定序号的断点
(5)打印变量值
命令:p expression
参数:expression Python表达式
(6)逐行调试命令
包括 s ,n , r 这3个相似的命令,区别在如何对待函数上
命令1:s
说明:执行下一行(能够进入函数体)
命令2:n
说明:执行下一行(不会进入函数体)
命令3:r
说明:执行下一行(在函数中时会直接执行到函数返回处)
(7)非逐行调试命令
命令1:c
说明:持续执行下去,直到遇到一个断点
命令2:unt lineno
说明:持续执行直到运行到指定行(或遇到断点)
命令3j lineno
说明:直接跳转到指定行(注意,被跳过的代码不执行)
(8)查看函数参数
命令:a
说明:在函数中时打印函数的参数和参数的值
(9)打印变量类型
命令:whatis expression
说明:打印表达式的类型,常用来打印变量值
(10)启动交互式解释器
命令:interact
说明:启动一个python的交互式解释器,使用当前代码的全局命名空间(使用ctrl+d返回pdb)
(11)打印堆栈信息
命令:w
说明:打印堆栈信息,最新的帧在最底部。箭头表示当前帧。
(12)退出pdb
命令:q
命令行参数
1.sys
(1) program:
import sys
print(sys.argv) # sys.argv即为参数列表, 其中sys.argv[0]即为脚本名
(2) command line:
python test.py argv1 argv2 # 位置参数在调用时不需要在前边写上参数,在对应位置上引用即可;可选参数需要添加-para_name para
2.命令行参数解析库 argparse
2.1 基础用法
(1) 实例化解析器
parser = argparse.ArgumentParser()
(2) 参数解析
args = parser.parse_args() # 得到参数字典,调用时采用args.xx的格式
(3) 位置参数添加
parser.add_argument(name, help='str', type=...)
(4) 可选参数添加
parser.add_argument(['-short_name', ]'--long_name', help='str'[, choices=[list], action='store_true']) # 其中choices提供选择,避免程序出现bug;action避免命令行中只出现可选参数名而不输入时无法运行的情况,默认存储为布尔型,可以用来判断有无输入
2.2 子命令
子命令即将功能分解到不同子命令当中,比如pip install、pip uninstall
(1) 创建子命令载体
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers(help="sub-command help") # 为子命令提供载体
(2) 创建子命令
parser_a = subparsers.add_parser('command_name', help='str') # add_parser()方法返回ArgumentParser实体
(3) 为子命令添加参数
parser_a = subparsers.add_parser('command_name', help='str') # add_parser()方法返回ArgumentParser实体
版本控制
虚拟环境
-
虚拟环境的应用场景:
同时从事多个项目开发,而每个项目需求的框架库版本不一致;为了避免卸载重装不兼容造成管理困难,我们需要虚拟环境 -
虚拟环境的作用:
每一个环境都相当于一个新的Python。你可以在这个新的环境里安装三方库,环境与环境之间是相互隔离的,也就是说在A环境中安装的库只在A中使用,不会影响其他环境 -
虚拟环境使用方法:
借助conda管理
anaconda自带conda工具
(1)创建虚拟环境
conda create -n venv python=2.x/3.x
(2)激活虚拟环境
#on windows
activate venv
#on linux
source activate venv
(3)推出虚拟环境
#on windows
deactivate
#on linux
source deactivate
(4)删除虚拟环境
conda remove --name venv --all
(5)其他指令
// 列出系统存在虚拟环境
conda info -e
conda env list
// 查看当前环境下已安装的包
conda list
// 查看某个指定环境的已安装包
conda list -n venv
// 查找package信息
conda search numpy
// 安装package
conda install -n venv numpy
// 如果不用-n指定环境名称,则被安装在当前激活环境,也可以通过-c指定通过某个channel安装
// 更新package
conda update -n venv numpy
// 删除package
conda remove -n venv numpy -
虚拟环境如何在Pycharm中使用:
设置project interpreter,其中system interpreter是系统自己安装的Python,是本地环境;Virtual Environment是Python的虚拟环境,将环境打包隔离,推荐使用;conda Enviroment为anaconda附带安装的Python解释器;剩下一种是本地创建虚拟环境。
添加Virtual Environment,解释器在anaconda/envs/your_new_venv_name下。
参考链接:
- 最全的Python虚拟环境使用方法
评价:全面、新手友好 - Pycharm 2018 虚拟环境创建及解释器的设置(小白图解教程)
评价:图文配合、详细
与其他语言交互
近来用Python用的越来越多,对这种十分灵活的动态语言的哲学也有较深的理解。虽然Python有很多缺点,如没有强类型,GIL交错锁,没有编译因此效率底下,但因此一种典型而高效的工作流程是先用Python调用各种轮子,快速实现软件原型,然后再优化代码,将稳定的部分用C ++或其他编译语言进行重写,变成一个供调用的库。
C/C++
可采用 Cython 为 Python 编写 C 扩展。Cython 是编写、包裹外部 C/C++ 库的胶水代码,将 CPython 嵌入现有应用程序、加速 Python 代码执行的理想 C 模块语言。
- .pyx文件
.pyx 文件是由 Cython 编程语言 “编写” 而成的 Python 扩展模块源代码文件。
.pyx 文件类似于 C 语言的 .c 源代码文件,.pyx 文件中有 Cython 模块的源代码。
不像 Python 语言可直接解释使用的 .py 文件,.pyx 文件必须先被编译成 .c 文件,再编译成 .pyd (Windows 平台) 或 .so (Linux 平台) 文件,才可作为模块 import 导入使用。
编译方式包括如下:
(1)通过setup.py中调用Cython.Build进行编译
python setup.py build_ext -i # 通过Cython将.pyx文件编译为.c文件
# 通过C编译器将.c文件编译为.so文件(如在Windows上,则是.pyd文件)
推荐使用,原理也就是通过指定distutils或者setuptools库中的ext_modules参数来编译Cython代码。
简单的setup.py文件如下:
from distutils.core import setup
from Cython.Build import cythonize
setup(
name = 'Hello world app',
ext_modules = cythonize("hello.pyx"),
)
复杂项目的setup.py文件如下:
from distutils.core import setup
from distutils.extension import Extension
from Cython.Build import cythonize
extensions = [
Extension("Module Name", ["file1.pyx", "file2.cpp", ...],
include_dirs = [...],
libraries = [...],
library_dirs = [...]),
Extension("Module 2", ...)
]
setup(
name = "XXX",
ext_modules = cythonize(extensions),
)
Extension类的构造函数中添加合适的参数即可指定语言或者编译参数
或者是
setup(
name = "XXX",
ext_modules = extensions,
cmdclass={'build_ext': Cython.Build.build_ext}
)
(2)使用pyximport调用.pyx文件,这种方法.pyx文件相当于普通的.py文件
(3)在命令行使用cython命令从.pyx文件生成.c文件,再使用外部编译器将.c文件编译成Python可用的库
(4)使用Jupyter Notebook或者Sage Notebook直接运行Cython代码