基本语法 注释 单行:#
多行:'''
或"""
1 2 3 4 a = b + c + \ d + e + \ f
变量类型 查看类型 type()
查看变量类型
isinstance(a, (类型1, ...))
判断是否是其中一种类型或子类
数字
int
bool(True/False)
float
complex(复数)
/
返回浮点数,//
返回整数的部分
字符串 单行字符串可用''
或""
,多行字符串可用''' '''
或""" """
转义符号\
不让\
生效,在引号前加r
可用+
连接字符串,*
重复字符串
字符串是不可改变量
切片
左闭右开
-1为末尾位置
还可加上步长,步长-1表示逆向
格式化
1 2 3 4 5 6 7 8 print ("我叫 %s 今年 %d 岁!" % ('小明' , 10 )) name = 'aaa' print (f'Hello {name} ' ) w = {'name' : 'baidu' , 'url' : 'www.baidu.com' }print (f'{w["name" ]} : {w["url" ]} ' )
列表 列表的元素是可改变的
1 2 3 4 5 6 a = [1 , 2 , 3 , 4 , 5 , 6 ]print (a[1 : 2 ]) print (a[1 :]) a[1 ] = 0 print (a)
列表操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 list1 = [1 , 2 , 3 ] list1.append(4 )print (list1) del list1[0 ]print (list1) import operator list1 = [1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 ] list2 = [1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 ]print (operator.eq(list1, list2))
元组 元组的元素不可以改变
可以把字符串看成特殊的元组
1 2 3 4 5 tup = (1 , ) a = (1 ) b = () print (type (tup)) print (type (a))
集合 集合的元素可变,唯一
创建可用{}
或set()
,空集合要用set
1 2 3 4 5 6 7 8 9 10 11 12 a = set ('abracadabra' ) b = set ('alacazam' )print (a)print (a - b) print (a | b) print (a & b) print (a ^ b)
字典 创建可用{}
或dict
,空字典可用{}
创建
key必须为不可变类型(数字、字符串、元组、布尔等)
1 2 3 4 a = {'a' : 1 , 'b' : 2 , 'c' : 3 , 4 : 'd' }print (a) print (a['a' ]) print (a[4 ])
字典操作
1 2 3 4 5 6 7 8 d = {1 : 1 , 2 : 2 , 3 : 3 }del d[1 ]print (d) d.clear()print (d)
输入输出 1 2 3 4 5 6 price = input ("Enter price: " )print (price)print (price, end = '' )
format格式化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 print ("Hello, {}!" .format ("Alice" ))print ("Hello, {0}, you are {1} years old." .format ("Bob" , 25 ))print ("Site name: {name}, Rank: {rank}" .format (name="Google" , rank=1 )) user = {"name" : "Alice" , "age" : 18 }print ("Name: {0[name]}, Age: {0[age]}" .format (user)) data = {"site" : "Google" , "rank" : 1 }print ("Site: {site}, Rank: {rank}" .format (**data))
格式化控制符
格式符
含义
示例值
示例结果
d
十进制整数
{0:d}
42
f
浮点数(默认 6 位)
{0:f}
3.141593
.2f
保留 2 位小数
{0:.2f}
3.14
>10
右对齐,占 10 宽度
{0:>10}
text
<10
左对齐,占 10 宽度
{0:<10}
text
^10
居中,占 10 宽度
{0:^10}
text
,
千位分隔符
{0:,}
1,000,000
%
百分比(乘以 100)
{0:.2%}
25.00%
条件/循环
导入模块 导入模块的搜索路径:
当前目录
环境变量 PYTHONPATH
指定的目录
Python 标准库目录
.pth
文件中指定的目录
1 2 3 4 5 6 7 8 import sysfrom sys import argv, pathfrom sys import *
每个模块都有一个__name__
属性
如果模块是被直接运行,__name__
的值为 __main__
。
如果模块是被导入的,__name__
的值为模块名。
数学函数
abs(): 绝对值
ceil()/floor(): 向上/向下取整
round(): 四舍五入
cmp(): 比较两个数
max()/min(): 取最大/最小值
pow(): 开方
sqrt(): 平方根
错误异常 处理异常
1 2 3 4 5 6 7 8 9 10 11 try : except ExceptionType1: except ExceptionType2 as e: else : finally :
抛出异常
1 2 3 4 def sqrt (x ): if x < 0 : raise ValueError("不能对负数开平方" ) return x ** 0.5
常见异常类型
异常名
说明
ValueError
参数类型/值不合法
ZeroDivisionError
除以 0
IndexError
索引超出范围
KeyError
字典中键不存在
FileNotFoundError
打开的文件不存在
TypeError
操作/函数类型不对
NameError
使用了未定义的变量
自定义异常
1 2 3 4 5 6 7 8 9 10 class MyError (Exception ): def __init__ (self, message ): self.message = message def __str__ (self ): return self.messagetry : raise MyError("MyError" )except MyError as e: print (e)
文件 打开文件
1 f = open (file, mode='r' , encoding=None )
打开模式
模式
含义
文件不存在时行为
可读
可写
是否清空原文件
r
只读
❌ 报错
✅
❌
否
w
只写
✅ 创建新文件
❌
✅
✅ 清空
a
追加写入
✅ 创建新文件
❌
✅
❌(在末尾写)
r+
读写
❌ 报错
✅
✅
❌
w+
写读(先清空)
✅ 创建新文件
✅
✅
✅ 清空
a+
读写(追加写入)
✅ 创建新文件
✅
✅
❌(只追加)
rb
/wb
等
二进制读写
适合图片、音频等
看上面
看上面
看上面
写入文件
使用with open() as f会自动关闭文件,不然要手动f.close()
1 2 3 4 5 6 7 8 with open ("test.txt" , "w" , encoding="utf-8" ) as f: f.write("Hello, world!\n" ) f.write("Second line.\n" )with open ("test.txt" , "a" , encoding="utf-8" ) as f: f.write("Appended line.\n" )
读取文件
1 2 3 4 5 6 7 8 9 10 11 12 13 with open ("test.txt" , "r" , encoding="utf-8" ) as f: content = f.read() print (content)with open ("test.txt" , "r" , encoding="utf-8" ) as f: lines = f.readlines() for line in lines: print (line.strip()) f.readline()
迭代器 访问集合元素的一种方式
可以记住遍历的位置的对象,只能往前不会后退
使用 1 2 3 4 5 6 7 8 9 10 11 a = [1 , 2 , 3 ] b = iter (a)print (next (b)) print (next (b)) print (next (b)) print (next (b)) for i in iter (a): print (i)
创建迭代器 实现__iter__()
和__next__()
方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 class MyNum : def __iter__ (self ): self.num = 0 return self def __next__ (self ): tmp = self.num if tmp < 20 : self.num += 1 return tmp else : raise StopIteration myclass = MyNum() it = iter (myclass)for i in it: print (i)
生成器 使用了yield
的函数 被称为生成器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 def countdown (n ): while n > 0 : yield n n -= 1 generator = countdown(5 ) print (next (generator)) print (next (generator)) print (next (generator)) for value in generator: print (value)
函数 不定长参数
1 2 3 4 5 6 7 def method (var1, *var2 ): print (var1, " " ,var2) method(1 ) method(1 , 2 ) method(1 , 2 , 3 )
1 2 3 4 5 6 7 8 9 10 11 12 def method (var1, *var2, **var3 ): print (var1) print (var2) print (var3) method(1 ,2 ,3 ,4 ,5 , a = 1 , b = 2 )''' 1 (2, 3, 4, 5) {'a': 1, 'b': 2} '''
匿名函数
作用是为了简洁,性能上和普通函数没差
1 2 3 4 5 sum = lambda arg1, arg2: arg1 + arg2print ("相加后的值为 : " , sum (10 , 20 )) print ("相加后的值为 : " , sum (20 , 20 ))
函数装饰器 函数装饰器是一种函数,它接受一个函数作为参数,并返回一个新的函数或修改原来的函数
用于不修改原函数的基础上动态地增加或修改函数的功能
类似java的注解+AOP
基本语法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 def decorator_function (original_function ): def wrapper (*args, **kwargs ): before_call_code() result = original_function(*args, **kwargs) after_call_code() return result return wrapper@decorator_function def target_function (arg1, arg2 ): pass
实例 :函数执行时间
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 import timedef time_logger (func ): def wrapper (*args, **kwargs ): start_time = time.time() res = func(*args, **kwargs) end_time = time.time() print ("参数: " , args) print ("执行时间: " , end_time - start_time) return res return wrapper@time_logger def say_hello (name ): print ("Hello! " , name) time.sleep(0.5 ) say_hello("Alice" )
实例 :带参数的装饰器
1 2 3 4 5 6 7 8 9 10 11 12 13 def repeat (n ): def decorator (func ): def wrapper (*args, **kwargs ): for i in range (n): func(*args, **kwargs) return wrapper return decorator@repeat(3 ) def say_hello (): print ("Hello World!" ) say_hello()
类装饰器 类装饰器用于动态修改类行为
实例 :实现类的单例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 class SingletonDecorator : """类装饰器,使目标类变成单例模式""" def __init__ (self, cls ): self.cls = cls self.instance = None def __call__ (self, *args, **kwargs ): """拦截实例化过程,确保只创建一个实例""" if self.instance is None : self.instance = self.cls(*args, **kwargs) return self.instance@SingletonDecorator class Database : def __init__ (self ): print ("Database 初始化" ) db1 = Database() db2 = Database()print (db1 is db2)
面向对象 构造方法 __init()__
,创建对象时自动调用
不写默认是个空的构造方法
1 2 3 4 5 6 7 8 class Person : def __init__ (self, name, age ): self.name = name self.age = age p = Person("John" , 22 )print (p.age)print (p.name)
类方法 类方法用def
定义,且第一个参数要为self
继承 子类继承父类的属性和方法
子类里可用super().
来调用父类的方法
1 2 3 4 5 6 7 8 9 10 11 class Animal : def speak (self ): print ("动物在叫" )class Dog (Animal ): def bark (self ): print ("汪汪汪" ) d = Dog() d.speak() d.bark()
多继承 时决定调用哪个类的方法,按从左到右的优先级
即先找自己,在从左到右找父类(如果父类也有父类,则会顺着它的父类找上去)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 class A : def hello (self ): print ("A" )class B (A ): def hello (self ): print ("B" )class C (A ): def hello (self ): print ("C" )class D (B, C): pass D().hello()
私有属性和方法 定义:在属性或方法前加__
私有属性和方法只能在本类中访问
python的私有并不是真的私有,只是改了其名字,变为_类型__属性名
1 2 3 4 5 6 7 8 9 10 11 12 13 class Person : def __init__ (self, name, age ): self.__name = name self.__age = age def __say_secret (self ): print ("这是一个秘密" ) def show (self ): print (f"{self.__name} , {self.__age} " ) self.__say_secret()print (Person("Tom" , 20 ).show())
魔法方法 魔法方法是 Python 自动调用的一些特殊方法
方法
作用
__init__(self, ...)
构造函数,创建对象时调用
__new__(cls, ...)
真正创建对象的方法,__init__
前执行(用于元类)
__del__(self)
析构函数,删除对象时调用
__str__()
print(obj)
时调用
__repr__()
解释器或 repr(obj)
时调用
运算符重载
方法
对应操作
__add__
+
加法
__sub__
-
减法
__mul__
*
乘法
__eq__
==
比较
__lt__
<
小于
多线程 Python的多线程是并发 的,而非真正的并行
CPython使用全局解释器锁(GIL)来保证线程安全,即同一时刻只有一个线程可以执行Python字节码。即使有多核CPU,GIL也会阻止多线程的并行 执行
通过threading
模块来使用多线程
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 import threadingimport timedef say_hello (): for i in range (3 ): print (f"线程 {threading.current_thread().name} 打招呼" ) time.sleep(1 ) t1 = threading.Thread(target=say_hello, name='T1' ) t2 = threading.Thread(target=say_hello, name='T2' ) t1.start() t2.start() t1.join() t2.join()print ("主线程结束" )
功能
说明
Thread(target=...)
创建线程并指定要执行的函数
start()
启动线程
join()
阻塞,直到被调用线程终止
current_thread()
获取当前线程信息
Lock()
创建互斥锁,防止多线程同时修改共享数据
enumerate()
返回一个包含正在运行的线程的列表
active_count()
返回正在运行的线程数量
守护线程
主线程会等待普通线程结束后才结束,而不会等待守护线程
要在start()
前设置t.daemon = True
才为守护线程
适合做后台服务或辅助任务
线程同步 互斥锁
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 import threading count = 0 lock = threading.Lock()def add (): global count for _ in range (100000 ): with lock: count += 1 t1 = threading.Thread(target=add) t2 = threading.Thread(target=add) t1.start() t2.start() t1.join() t2.join()print ("count:" , count)
可重入锁
threading.RLock()
支持一个线程加多次锁,适合递归或多个函数都加锁时
信号量
1 2 3 4 5 6 7 8 9 import threadingimport time sem = threading.Semaphore(3 ) def task (): with sem: print (threading.current_thread().name, "进入" ) time.sleep(2 )
线程通知
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 import threadingimport time event = threading.Event()def worker (): print ("等待事件触发..." ) event.wait() print ("事件已触发,开始工作" ) t = threading.Thread(target=worker) t.start() time.sleep(3 )print ("触发事件!" ) event.set ()
JSON 通过dump()
转换为json格式,load()
读取json
1 2 3 4 5 6 7 8 9 10 11 import json data = {'name' : 'Bob' , 'age' : 30 , 'is_student' : True }with open ('data.json' , 'w' ) as f: json.dump(data, f, indent=4 , ensure_ascii=False )with open ('data.json' , 'r' ) as f: data = json.load(f) print (data)
Numpy
NumPy 是一个用于处理数组的 Python 库。
创建数组 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 import numpy as np ar1 = np.array([1 , 2 , 3 ])print (ar1) ar2 = np.array([1.0 , 2 , 3 ])print (ar2) arr1 = np.ones((3 , 3 )) print (arr1)print (arr1.shape) print (arr1.reshape((1 , -1 ))) print (arr1.reshape(-1 )) arr1 = np.arange(1 , 10 )print (arr1) arr1 = np.random.random(3 )print (arr1) arr1 = np.random.normal(0 , 1 , 100 )print (arr1)
访问数组 1 2 3 4 5 6 7 arr1 = np.array( [[1 , 2 , 3 ], [4 , 5 , 6 ]])print (arr1[0 , 1 ])print (arr1[ [0 , 1 ], [1 , 2 ] ])
数组操作 切片
numpy的切片仅是原数组的视图,原python的是拷贝。要拷贝用数组.copy()
1 2 3 4 5 6 7 8 9 10 arr1 = np.arange(1 , 21 ).reshape(4 , 5 )print (arr1)print (arr1[1 :3 , 1 :-1 ])
翻转 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 import numpy as np arr1 = np.arange(10 ) arr1 = np.flipud(arr1)print (arr1) arr1 = np.arange(1 , 21 ).reshape(4 , 5 ) arr1 = np.fliplr(arr1)print (arr1) arr1 = np.flipud(arr1)print (arr1)
转置
重塑 1 2 arr2 = arr1.reshape((3 , 4 ))
拼接 1 2 3 4 5 6 7 8 9 10 arr1 = np.array([1 , 2 , 3 ]) arr2 = np.array([4 , 5 , 6 ])print (np.concatenate((arr1, arr2))) arr1 = np.array([[1 , 2 , 3 ], [4 , 5 , 6 ]]) arr2 = np.array([[7 , 8 , 9 ]])print (np.concatenate((arr1, arr2)))
截断 1 2 3 4 5 6 7 8 9 10 11 arr1 = np.array([1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 ])print (np.split(arr1, (2 , 4 ))) arr1 = np.arange(8 ).reshape(2 , -1 )print (np.split(arr1, (1 , ), axis=1 ))
矩阵运算 相乘 1 2 3 4 5 6 7 8 9 10 arr1 = np.arange(5 ) arr2 = np.arange(5 )print (np.dot(arr1, arr2)) arr1 = np.arange(5 ) arr2 = np.arange(15 ).reshape(5 , 3 )print (np.dot(arr1, arr2))
数学函数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 arr1 = np.array((-10 , 0 , 10 ))print (np.abs (arr1)) np.sin(arr1) np.cos(arr1) np.tan(arr1) np.exp() print ("2^x = " , 2 ** arr1) np.log(arr1)print ("log2(x) = " , np.log(arr1) / np.log(2 )) arr1 = np.array(((2 , 4 , 6 ), (1 , 2 , 3 )))print (np.max (arr1, axis=0 ))
布尔 1 2 3 4 5 6 7 8 9 10 11 12 arr1 = np.array((False , False , True ))print (np.any (arr1)) print (np.all (arr1)) arr1 = np.array((1 , 2 , 3 ))print (arr1[ arr1 > 1 ]) arr1 = np.array((1 , 2 , 3 ))print (np.where(arr1 > 1 ))
Pandas
Pandas 提供了易于使用的数据结构和数据分析工具,特别适用于处理结构化数据,如表格型数据。可以看做是numpy的扩展
创建数据结构 Series
和字典有点像,但这个是有序的,且key可重复
1 2 3 4 5 6 7 8 9 10 11 12 13 14 import pandas as pd dict_v = {'a' : 0 , 'b' : 0.25 , 'c' : 0.75 , 'd' : 1 } sr = pd.Series(dict_v)print (sr) k = ['a' , 'b' , 'c' , 'd' ] v = [0 , 0.25 , 0.75 , 1 ] sr = pd.Series(data=v, index=k)print (sr)
DataFrame
类似二维表格
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 v1 = [53 , 64 , 72 , 82 ] v2 = ['女' , '男' , '女' , '男' ] i = ['1号' , '2号' , '3号' , '4号' ] sr1 = pd.Series(v1, index=i) i[3 ] = '6号' sr2 = pd.Series(v2, index=i) df = pd.DataFrame({'年龄' : sr1, '性别' : sr2})print (df) v = np.array([ [53 , '女' ], [64 , '男' ], [72 , '女' ], [82 , '男' ] ]) i = ['1号' , '2号' , '3号' , '4号' ] c = ['年龄' , '性别' ] df = pd.DataFrame(v, index=i, columns=c)print (df)
访问 Series 如果key是数字的话,会和下标混淆,所有可以用loc
显示索引(key),iloc
隐式索引(下标)
1 2 3 4 5 6 7 8 9 10 11 k = ['a' , 'b' , 'c' , 'd' ] v = [0 , 0.25 , 0.75 , 1 ] sr = pd.Series(data=v, index=k)print (sr['c' ])print (sr.loc['c' ])print (sr['a' :'c' ])print (sr[0 :2 ])
DataFrame 必须使用索引器
1 2 3 4 5 6 7 8 9 10 11 12 v = np.array([ [53 , '女' ], [64 , '男' ], [72 , '女' ], [82 , '男' ] ]) i = ['1号' , '2号' , '3号' , '4号' ] c = ['年龄' , '性别' ] df = pd.DataFrame(v, index=i, columns=c)print (df.iloc[0 ][0 ])print (df.loc['1号' ]['年龄' ])print (df.loc['1号' :'3号' , '年龄' ])
对象变形 转置 1 2 3 4 5 6 7 v = [[53 , 64 , 72 , 82 ], ['女' , '男' , '女' , '男' ]] i = ['年龄' , '性别' ] c = ['1号' , '2号' , '3号' , '4号' ] df = pd.DataFrame(v, index=i, columns=c)print (df.T)
翻转 1 2 3 4 print (df.T.iloc[: : -1 , :])print (df.T.iloc[:, : : -1 ])
重塑 1 2 3 4 5 6 7 8 9 10 11 12 i = ['1号' , '2号' , '3号' , '4号' ] v1 = [10 , 20 , 30 , 40 ] v2 = ['女' , '男' , '女' , '男' ] v3 = [1 , 2 , 3 , 4 ] sr1 = pd.Series(v1, index=i) sr2 = pd.Series(v2, index=i) sr3 = pd.Series(v3, index=i) df = pd.DataFrame({'年龄' : sr1, '性别' : sr2}) df['拍照' ] = sr3print (df)
合并 1 2 3 4 pd.concat({sr1, sr2}, axis = 0 ) pd.concat({sr1, sr2}, axis = 1 )
缺失值 找缺失值 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 import pandas as pd k = [1 , 2 , 3 , 4 ] v = [1 , 2 , 3 , None ] sr = pd.Series(v, index=k)print (sr.isnull()) v = [ [None , 1 ], [64 , None ], [72 , 3 ], [82 , 1 ]] i = [ '1号' , '2号' , '3号' , '4号' ] c = [ '年龄' , '牌照' ] df = pd.DataFrame(v, index=i, columns=c)print (df.isnull())
剔除缺失值 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 k = [1 , 2 , 3 , 4 ] v = [1 , 2 , 3 , None ] sr = pd.Series(v, index=k)print (sr.dropna()) v = [ [None , 1 ], [64 , None ], [72 , 3 ], [82 , 1 ]] i = [ '1号' , '2号' , '3号' , '4号' ] c = [ '年龄' , '牌照' ] df = pd.DataFrame(v, index=i, columns=c)print (df.dropna()) print (df.dropna(how='all' ))
填充缺失值 1 2 3 4 5 6 7 8 9 10 11 12 13 14 k = [1 , 2 , 3 , 4 ] v = [1 , 2 , 3 , None ] sr = pd.Series(v, index=k)print (sr.fillna(0 )) v = [ [None , 1 ], [64 , None ], [72 , 3 ], [82 , 1 ]] i = [ '1号' , '2号' , '3号' , '4号' ] c = [ '年龄' , '牌照' ] df = pd.DataFrame(v, index=i, columns=c)print (df.fillna(0 ))
Excel 导入Excel 1 2 3 4 5 import pandas as pd df = pd.read_csv('test.csv' , index_col=0 , encoding='gbk' )
读取数据 1 2 3 4 5 6 7 8 9 print (df.head()) df.max () df.min () df.mean() df.std() df.sum () df.describe()
数据透视 1 2 3 4 5 6 7 8 9 10 11 df.pivot_table(列名1 , index=列名2 ) df.pivot_table(列名1 , index=列名2 , columns=列名3 ) pd.cut( df['年龄' ], [0 , 25 , 125 ]) pd.qcut( df['费用' ], 2 )