python
Python下载安装
选择32bit
版本进行安装:官方网址:https://www.python.org
python优缺点
优点:
- 简单易学:python代码简洁、语法规范,容易上手
- 开源:用户可以免费使用
- 可移植性好:在不同的平台都可以运行,需要注意运行环境的配置
- 可扩展性:python拥有丰富的第三方库
缺点:
- 在底层做了很多工作,运行速度比C、Java等慢很多
- 由于各种扩展库太庞大,导致配置相关包有点困难
- 不同版本的包可能存在不兼容的情况
- 从2.x版本升级到3.x版本之后,很多语句和功能无法跨版本运行
python支持的数据类型
类型名 | 说明 | 描述 |
str | 字符串类型 | 一段字符串 |
int | 整形 | 整数,比如1,2,3 |
float | 浮点型 | 比如0.1,0.336 |
bool | 逻辑值 | True或者False |
complex | 复数 | 数学上的概念 |
bytes | 字节型 | 原始的数据类型,可以理解为0 1代码 |
list | 列表 | 有序可修改的列表 |
tuple | 元组 | 元组比较特别,他是一个不可以修改的有序列表 |
set | 集合 | 无序、不重复值的合集 |
dict(map) | 字典 | 类似于map |
python声明一个变量时,可以不声明他的类型,在赋值的时候确定类型
声明容器类型变量,内部的元素类型任意
由于列表、集合和字典非常频繁的使用,在数据挖掘的过程中,数据通常以向量的方式表示、存储在列表中。
字符串
使用单引号或双引号以及三引号:
print ('I love China.')
print ("Let's go!")
print ('"Life is short , you need Python!"')
三引号可以不加转义字符进行换行:
print ("""I love China.""")
print ('''I love China.''')
字符串内容中的引号使用转义字符 \ ,字符串可以使用任意一种引号包裹:
print ("\"Life is short , Let\'s learn python\"")
print ('\"Life is short , Let\'s learn python\"')
- 在字符串前面加一个
r
,转义字符就不会在生效啦!
字符串的加乘法
字符串加法:
字符串的拼接
字符串的乘法:
字符串的数量的乘数倍
eg:print ("我会打印三千行!\n" * 3000)
bool类型
定义为False的对象:
None 和 False(首字母不可以小写)
值为0的数字类型:0, 0.0, 0j, Decimal(0), Fraction(0,1)
空的序列和集合:'', (), [], {}, set(), range(0)
python相关语句
if循环:
if (条件):
true
else
false
注意:python以缩进判断是否是同一块内容
while循环:
while (条件):
true
break:
break:跳出循环,结束
eg:
while true :
print ("true")
break
*:只会输出一遍 ture
random:
random 生成随机数:
import random (先进行导包)
random.randint(1,10):
生成一个1~10的随机数,两个参数表示生成随机数的范围
random.getstate():
获取随机数种子
random.setsate():
设置随机数种子
eg:(*:我亲切的称其为模拟运行结果展示--注释)
x = random.getstate()
random.randint(1,10)
*:7
random.randint(1,10)
*:2
random.randint(1,10)
*:3
random.randint(1,10)
*:3
random.setstate(x)
random.randint(1,10)
*:7
random.randint(1,10)
*:2
random.randint(1,10)
*:3
random.randint(1,10)
*:3
这两次生成的随机数是相同的。
数字类型
整数 – integers
浮点数 – floating point numbers
复数 – complex numbers
x = 1 + 2j
x.real:获取实部
*:1.0
x.imag:获取虚部
*:2.0
运算符
比较运算符
运算符 | 含义 |
< | 判断左边是否小于右边 |
<= | 判断左边是否小于等于右边 |
> | 判断左边是否大于右边 |
>= | 判断左边是否大于等于右边 |
== | 判断两边是否相等 |
!= | 判断两边是否不相等 |
is | 判断两个对象的id是否相等 |
is not | 判断两个对象的id是否不相等 |
算术运算符
操作 | 结果 |
x + y | x加y的结果 |
x - y | x减y的结果 |
x * y | x乘以y的结果 |
x / y | x除以y的结果 |
x // y | x除以y的结果(地板除) |
x % y | x除以y的余数 |
-x | x的相反数 |
+x | x本身 |
abs(x) | x的绝对值 |
int(x) | 将x转换成整数 |
float(x) | 将x转换成浮点数 |
complex(re,im) | 返回一个复数,re是实部,im是虚部 |
c.conjugate | 返回c的共轭复数 |
divmod(x,y) | 返回(x//y,x%y) |
pow(x,y) | 计算x的y次方 |
x ** y | 计算x的y次方 |
说明:
地板除 -- 结果保留整数(向下取整)
complex('1+2j') -- 字符串中不能有空格
pow函数当传入三个参数时,会将幂运算的结果与第三个参数进行取余
eg:
pow(2, 3, 5) = 2 ** 3 % 5 = 3
逻辑运算符
运算符 | 含义 |
and | 左边和右边同时为True,结果为True |
or | 左边或右边其中一个为True,结果为True |
not | 如果操作数为True,结果为False 如果操作数为False,结果为True |
说明:
Python 中任何对象对能直接进行
真值测试
---- 测试该对象的布尔类型值为True或者False,用于 if 或者 while 语句的条件判断,也可以作为布尔逻辑运算符的操作数
短路逻辑的核心思想:从左往右,只有当第一个操作数的值无法确定逻辑运算的结果时,才对第二个操作数进行求值。
(not 1) or (0 and 1) or (3 and 4) or (5 and 6) or (7 and 8 and 9) == 4
*:False or 0 or 4 or 6 or 9
运算符优先级
运算符说明 | Python运算符 | 优先级 | 结合性 | 优先级顺序 |
---|---|---|---|---|
小括号 | ( ) | 19 | 无 | 高 ︿ | | | | | | | | | | | | | | | | | | | | | | 低 |
索引运算符 | x[i] 或 x[i1: i2 [:i3]] | 18 | 左 | |
属性访问 | x.attribute | 17 | 左 | |
乘方 | ** | 16 | 右 | |
按位取反 | ~ | 15 | 右 | |
符号运算符 | +(正号)、-(负号) | 14 | 右 | |
乘除 | *、/、//、% | 13 | 左 | |
加减 | +、- | 12 | 左 | |
位移 | >>、<< | 11 | 左 | |
按位与 | & | 10 | 右 | |
按位异或 | ^ | 9 | 左 | |
按位或 | | | 8 | 左 | |
比较运算符 | ==、!=、>、>=、<、<= | 7 | 左 | |
is 运算符 | is、is not | 6 | 左 | |
in 运算符 | in、not in | 5 | 左 | |
逻辑非 | not | 4 | 右 | |
逻辑与 | and | 3 | 左 | |
逻辑或 | or | 2 | 左 | |
逗号运算符 | exp1, exp2 | 1 | 左 |
eg:
not 1 or 0 and 1 or 3 and 4 or 5 and 6 or 7 and 8 and 9
*: False or 0 or 4 or 6 or 9
*: 4
流程图 – Flowchart
思维导图 – Mind Map
分支和循环 – branch and loop
分支结构 – if
1. 判断一个条件,如果这个条件成立,就执行其包含的某条件语句或某个代码块
if condition :
statement(s)
2. 判断一个条件:
如果条件成立,就执行其包含的某条语句或某个代码块
如果条件不成立,就执行另外的某条语句或某个代码块
if condition :
statement(s)
else :
statement(s)
3. 判断多个条件,如果第一个条件不成立,则继续判断第2个条件,如果第2个条件不成立,则接着判断第3个条件·····
if condition1 :
statement(s)
elif condition2 :
statement(s)
elif condition3 :
statement(s)
...
4. 在第3中情况下添加一个else,表示上面所有的条件均不成立的情况下,执行某条语句或某个代码块
if condition1 :
statement(s)
elif condition2 :
statement(s)
elif condition3 :
statement(s)
...
else :
statement(s)
5. 条件表达式:
条件成立时执行的语句 if condition else 条件不成立时执行的语句
eg:
age = 16
print ("抱歉,未满18岁禁止访问。") if age < 18 else print ('欢迎您来^0^')
eg:判断成绩等级
- 使用第4方式
score = input("请输入你的成绩:")
score = int (score)
if 0 <= score <= 60 :
print ('D')
elif score <= 70 :
print ('C')
elif score <= 80 :
print ('B')
elif score <= 90 :
print ('A')
elif score <= 100 :
print ('S')
else :
print ("你输入的成绩有误!请重新输入0~100之间的成绩")
- 使用第5方式
score = 66
level = ( 'D' if 0 <= score < 60 else
'C' if 60 <= score <80 else
'B' if 80 <= score < 90 else
'A' if 90 <= score <100 else
'S' if score == 100 else
'请输入0~100之间的成绩^o^')
print (level)
分支结构的嵌套 – nested branches
age = 18
isMale = True
if age < 18 :
print ("抱歉,未满18岁禁止访问。")
else :
if isMale :
print ('任君选购!')
else :
print ('抱歉!本店商品可能不太适合小公举哦~')
循环结构
break:
跳出循环 -- 一层循环体
continue:
跳出本轮循环
else :
当循环条件不在为真的时候执行
while 循环
while condition :
statement(s)
for 循环
for 变量 in 可迭代对象 :
statement(s)
整数类型不是可迭代对象,可以用range -- 将整数转换成整数数列:
range(stop)
range(start,stop)
range(start,stop,step) -- step 可以是负数
打印三角形
for i in range(1,6):
print(' '*(5-i),'*'*(2*i-1))
循环结构的嵌套 – nested loop
九九乘法表
i = 1
while i <= 9:
j = 1
while j <= i:
print(j,"*",i,"=",j*i,'\t',end='')
j += 1
print()
i += 1
break – 跳出一层循环体
for 循环嵌套 – 找到 [2,10)之间的素数
列表
rhyme = [1,2,3,4,5,'上山打老虎']
获取列表最后一个元素:
rhyme[len(rhymr) - 1]
rhyme[-1] -- 倒找索引,倒数第二个就是 -2
列表切片
1. [start:stop], -- 左闭右开,不包含stop
rhyme[0:3] -- [1,2,3]
rhyme[3:6] -- [4,5,'上山打老虎']
rhyme[:3] -- [1,2,3]
rhyme[3:] -- [4,5,'上山打老虎']
rhyme[:] -- [1,2,3,4,5,'上山打老虎']
2. [start:stop:step] -- step可以是负数
rhyme[0:6:2] -- [1,3,5]
rhyme[::2] -- [1,3,5]
rhyme[::-1] -- 列表倒序输出 -- ['上山打老虎',5,4,3,2,1]
列表添加元素
1. append() -- 添加一个元素至列表末尾
heros = ["钢铁侠","绿巨人"]
heros.append("黑寡妇") -- heros -- ["钢铁侠","绿巨人","黑寡妇"]
2. extend() -- 添加一个可迭代对象至列表末尾
heros.extend(["鹰眼","灭霸","雷神"])
heros -- ["钢铁侠","绿巨人","黑寡妇","鹰眼","灭霸","雷神"]
注:extend()方法的参数必须是一个可迭代对象,新的内容是追加到愿列表的最后一个元素后面。
3. 切片添加元素:
s = [1,2,3]
s[len(s):] = [4] -- s -- [1,2,3,4]
s[len(s):] = [5,6,7] -- s-- [1,2,3,4,5,6,7]
4. insert() -- 列表任意位置添加元素
insert(插入位置下标,待插入元素)
s.insert(0,0) -- s -- [0,1,2,3,4,5,6,7]
列表删除元素
1. remove() -- 将指定的元素删除
heros.remove("灭霸") -- heros -- ["钢铁侠","绿巨人","黑寡妇","鹰眼","雷神"]
注:
(1)如果列表中存在多个匹配的元素,那么remove只会删除第一个。
(2) 如果指定的元素不存在,那么程序就会报错。
2. pop() -- 删除指定元素索引位置的元素
heros.pop(2) -- '黑寡妇' -- heros -- ["钢铁侠","绿巨人","鹰眼","雷神"]
3. clear() -- 清空列表元素
heros.clear() -- heros -- []
列表元素替换
1. 直接使用元素下标进行赋值操作
heros = ["钢铁侠","绿巨人","黑寡妇","鹰眼","灭霸","雷神"]
heros[4] = "钢铁侠" -- heros -- ["钢铁侠","绿巨人","黑寡妇","鹰眼","钢铁侠","雷神"]
2. 切片替换
heros[3:] = ["武松","林冲","李逵"] -- heros -- ["钢铁侠","绿巨人","黑寡妇","武松","林冲","李逵"]
注:实现过程:(1)将赋值号(=)左边指定的内容删除
(2)将包含在赋值号(=)右边的可迭代对象中的片段插入左边被删除的位置
列表排序
sort() -- 将列表元素 从小到大 进行排序
reverse() -- 将列表元素反转
sort(key=None,reverse=False) -- key参数用于指定一个比较函数,reverse参数用于指定排序结果是否反转
nums = [3,1,8,4,7]
nums.sort() -- [1,3,4,7,8]
nums.reverse() -- [8,7,4,3,1]
s = [3,5,1,6,2]
s.sort(reverse=True) -- [6,5,3,2,1]
列表元素查找
1. count() -- 查找指定元素个数
nums = [6,3,3,3,3,5]
nums.count(3) -- 4
2. index() -- 查找列表元素索引值
nums.index(5) -- 5
利用查找的索引值进行指定元素的替换:
nums[nums.index(5)] = 2 -- [6, 3, 3, 3, 3, 2]
注:如果有多个相同的元素,返回第一个的索引值
3. index(x,start,end) -- 查找指定范围内的元素索引
列表拷贝
浅拷贝:
1. copy() -- 将列表复制给一个新的列表
nums = [1,2,3,4]
nums_copy1 = nums.copy() -- nums_copy1 -- [1,2,3,4]
2. 切片拷贝
nums_copy2 = nums[:] -- nums_copy2 -- [1,2,3,4]
列表的加法和乘法 – concatenation and multiplication of list
加法 -- 列表的拼接
乘法 -- 重复列表内容若干次
嵌套列表 – nested list
也就是所谓的多维列表:
matrix = [[1,2,3],[4,5,6],[7,8,9]]
matrix = [[1,2,3],
[4,5,6],
[7,8,9]]
访问嵌套列表 – access nested list
通过列表下标:
matrix = [[1,2,3],[4,5,6],[7,8,9]]
for i in matrix:
for each in i:
print(each,end=" ")
print()
1 2 3
4 5 6
7 8 9
matrix[i][j]:
matrix[0][0] == 1
循环创建嵌套列表
A = [None] * 3
for i in range(3):
A[i] = [0] * 3
A -- [[0,0,0],[0,0,0],[0,0,0]]
is – is operator
is 判断是不是同一个对象:
x = 'Xawang'
y = 'Xawang'
x is y -- True
x = [1,2,3]
y = [1,2,3]
x is y -- False
变量不是盒子 – Variables are not boxes
将一个变量赋值给另一个变量,其实就是将这个变量的引用传递给另一个变量:
x = [1,2,3]
y = x
x[1] = 1
x -- [1, 1, 3]
y -- [1, 1, 3]
浅拷贝和深拷贝 – Shallow and deep copy
浅拷贝 -- 使用 copy() 方法 或者使用 切片 进行的拷贝
浅拷贝拷贝的只是外层对象
x = [[1,2,3],[4,5,6],[7,8,9]]
y = x.copy()
x[1][1] = 0
x -- [[1, 2, 3], [4, 0, 6], [7, 8, 9]]
y -- [[1, 2, 3], [4, 0, 6], [7, 8, 9]]
import copy -- 导入copy模块
x = [[1,2,3],[4,5,6],[7,8,9]]
y = copy.copy(x)
x[1][1] = 0
x -- [[1, 2, 3], [4, 0, 6], [7, 8, 9]]
y -- [[1, 2, 3], [4, 0, 6], [7, 8, 9]]
深拷贝:
deepcopy -- 拷贝原对象的同时,也将对象中所有引用的子对象一并进行了拷贝
import copy
x = [[1,2,3],[4,5,6],[7,8,9]]
y = copy.copy(x)
x = [[1,2,3],[4,5,6],[7,8,9]]
y = copy.deepcopy(x)
x[1][1] = 0
x -- [[1, 2, 3], [4, 0, 6], [7, 8, 9]]
y -- [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
列表推导式 – list comprehension expression
[expression for target in iterble] -----> x = [i for i in range(10)]
将列表中所有元素的值变为原来的2倍:
1. for循环:
oho = [1,2,3,4,5]
for i in range(len(oho)):
oho[i] = oho[i] * 2
oho -- [2, 4, 6, 8, 10]
2. 列表推导式:
oho = [1,2,3,4,5]
oho = [i * 2 for i in oho]
oho -- [2, 4, 6, 8, 10]
*:ord() -- 将单个字符串转换为对应的编码(Unicode)
code = [ord(c) for c in "Xawang"]
code -- [88, 97, 119, 97, 110, 103]
获取第2列元素:
matrix = [[1,2,3],[4,5,6],[7,8,9]]
col2 = [x[1] for x in matrix]
col2 -- [2, 5, 8]
获取主对角线元素:
matrix = [[1,2,3],[4,5,6],[7,8,9]]
diag = [matrix[i][i] for i in range(len(matrix))]
diag -- [1,5,9]
获取另一条对角线上的元素:
diagram = [matrix[i][-i-1] for i in range(len(matrix))]
diagram -- [3,5,7]
[expression
for target in iterable if condition
]
- 先执行
for
循环 - 在执行
if
语句 - 最后执行
expression
表达式
0~10之间的偶数:
even = [i for i in range(10) if i % 2 == 0]
even -- [2,4,6,8]
寻找F开头的单词:
words = ["Great","Fish","Brilliant","Excellent","Fantastic"]
words_find = [find for find in words if find[0] == 'F']
words_find -- ['Fish', 'Fantastic']
[expression for target1 in iterable1 for target2 in iterable2 … for targetN in iterableN]
将二维列表降维:
matrix = [[1,2,3],[4,5,6],[7,8,9]]
flatten = [col for row in matrix for col in row]
flatten -- [1, 2, 3, 4, 5, 6, 7, 8, 9]
[x + y for x in "fish" for y in "Fish"]
等同于:
_ = []
for x in "fish":
for y in "Fish":
_.append(x + y)
[expression for target1 in iterable1 if condition1
for target2 in iterable2 if condition2
… for targetN in iterableN if conditionN
]
[[x,y] for x in range(10) if x % 2 == 0 for y in range(10) if y % 3 == 0]
等同于:
_ = []
for x in range(10):
if x % 2 == 0:
for y in range(10):
if y % 3 == 0:
_.append([x,y])
元组 – tuple
列表 - [元素1, 元素2, 元素3,···]
元组 - (元素1, 元素2, 元素3,···)
注:
1. 元组内容不可以修改
2. 在不产生歧义的情况下,元组的圆括号可以省略
3. 元组仅支持 copy() 和 index() 方法
4. 没有元组推导式
5. 元组同样支持切片操作
6. 元组可以使用列表推导式
7. 如果元组中的元素指向一个可变的列表,那么可以修改列表里面的内容
圆括号的必要性:
与其纠结什么时候省略圆括号不会带来问题,还不如一直都加上为妙!!
如何生成只有一个元素的元组:
加上一个','
type()可以查看变量类型:
x = (520)
type(x) -- <class 'int'>
x = (520,)
type(x) -- <class 'tuple'>
打包和解包
python的多重赋值:
x, y = 10, 20
其实是先将10,20打包成一个元组,在进行解包的过程:
_ = (10,20)
x, y = _
字符串和列表同样支持:
a, b, c = "ABC"
a--'A', b--'B', c--'C'
a, b, c = ['A','B','C']
a, b, c = "Xawang"
a--'X', b--'a', c--['w', 'a', 'n', 'g']
字符串
判断输入的一串数字是不是回文数:
*1:
_ = input("请输入一串数:")
iterable = list(_)
x = int((len(iterable)-1)/2)
temp = 0
for i in range(0,x):
if iterable[i] == iterable[len(iterable)-1-i]:
temp += 1
else:
print("不是回文数!")
break
if temp == x:
print("是回文数列")
*2 :
iterable = list(input("请输入一串数:"))
print("是回文数列") if iterable == iterable[::-1] else print("不是回文数!")
1. 大小写字母换来换去
1. capitalize() -- 将字符串的首字母大写,其余单词首字母小写,返回的是一个新的字符串
2. casefold() -- 返回一个全是小写的新字符串
3. title() -- 将字符串所有单词首字母大写,其余所有字母小写,返回新字符串
4. swapcase() -- 所有字母大小写反转,返回新字符串
5. upper() -- 将所有字母变为大写,返回新字符串
6. lower() -- 将所有字母变为小写,返回新字符串
2. 左中右对齐
1. center(width,fillchar=' ')
2. ljust(width,fillchar=' ')
3. rjust(width,fillchar=' ')
4. zfill(width) -- 左侧用0填充
*:
1. width设置的值小于字符串自身长度时,字符串原样输出
2. fillchar代表填充的字符,默认是空格
*:
x.center(40,"*") -- '*************wang xing wang*************'
x.rjust(40,"*") -- '**************************wang xing wang'
x.ljust(40,"*") -- 'wang xing wang**************************'
"-40".zfill(40) -- '-000000000000000000000000000000000000040'
3. 查找
1. count(sub[,start[,end]]) -- 用于查找sub子字符串在字符串中出现的次数
x.count("a")
x.count("a",0)
x.count("a",0,5)
2. find(sub[,start[,end]]) -- 从左往右sub第一次出现时的下标索引值
3. rfind(sub[,start[,end]]) -- 从右往左sub第一次出现时的下标索引值
4. index(sub[,start[,end]]) -- 从左往右sub第一次出现时的下标索引值
5. rindex(sub[,start[,end]]) -- 从右往左sub第一次出现时的下标索引值
注:
index和find的不同之处在于:
find在查找不到sub时,返回-1
index在查找不到sub时,抛出异常
4. 替换
1. expandtabs([tabsize=8]) -- 使用空格替换tab制表符,返回一个新字符串
2. replace(old,new,count=-1) -- 将字符串old代表的老字符串的一部分替换成new代表的新的字符串的一部分,count表示替换次数,默认替换全部
eg:
"oho,My God!".replace("oho","oh") -- "oh,My God!"
3. translate(table) -- 根据table指定的替换规则,将字符串中的内容进行替换
eg:
table = str.maketrans("ABCDEFG","1234567")
"I love China!".translate(table) -- 'I love 3hina!'
也可以直接将制作表格的方法直接当做translate的参数:
"I love China!".translate(str.maketrans("ABCDEFG","1234567"))
table = str.maketrans("ABCDEFG","1234567","love") -- 第三个参数表示将"love"忽略掉
eg:
"I love China!".translate(table) -- 'I 3hina!'
5. 判断
1. startswith(prefix[,start[,end]]) -- 用于判断子字符串是否出现在字符串的起始位置
2. endswith(suffix[,start[,end]]) -- 用于判断子字符串是否出现在结束位置
3. isupper() -- 是否所有字母都是大写字母
4. islower() -- 判断是否所有字母都是小写
5. istitle() -- 是否所有单词都以大写字母开头,其余都是小写字母
6. isalpha() -- 判断一个字符串中是否都是字母(空格不是字母)
7. isascii() -- 判断字符串是否为空或者都是ASCII码
8. isspace() -- 判断是不是一个空白字符串
9. isprintable() -- 判断是否所有字符都是可打印的
10. isdecimal() -- 是否是数字(123)
11. isdigit() -- 是否是数字(123,2²)
12. isnumeric() -- 是否是数字(123,2²,一二,ⅠⅡ)
13. isalnum() -- 是否是数字或者字母
14. isidentifier() -- 是否是一个合法标识符
15. iskeyword(str) -- 判断是不是python保留标识符
*:使用iskeyword()先导入keyword模块 -- import keyword
import keyword
keyword.iskeyword(str)
6. 截取
1. strip(chars=None)
2. lstrip(chars=None) -- 去除左侧chars
3. rstrip(chars=None) -- 去除右侧chars
*:chars是一个字符一个字符匹配,默认是空白
eg:"www.baidu.com".strip("wcom.") -- "baidu"
4. removeprefix(prefix) -- 删除指定的前缀
5. removesuffix(suffix) -- 删除指定的后缀
*:返回的都是新字符串
7. 拆分&拼接
1. partition(sep) -- 以sep为指定的分隔符进行切割,并且将切割后的结果返回一个三元组(三个元素的元组)
*:"www.baidu.com".partition(".") -- ('www', '.', 'baidu.com')
2. rpartition(sep) -- 从右侧开始寻找切割符
3. split(sep=None,maxsplit=-1) -- 将字符串进行切割,打包成列表进行返回(maxsplit代表切割次数)
4. rsplit(sep=None,maxsplit=-1) -- 从右向左
5. splitlines(keepends=False) -- 将字符串按行进行切割,以列表的形式返回(keepends表示切割后结果是否包含换行符,True表示包含--包含在前一个子字符串)
6. join(iterable) -- 将字符串进行拼接,通过分隔符调用
*:
".".join(["www","baidu","com"]) -- 'www.baidu.com'
"".join(["I love"," China"]) -- "I love China"
*:
使用join()方法进行字符串拼接,大数据量的情况下要比用+拼接快的多,效率更高
8. 字符串格式化
format():[[fill]align][sign][#][0][width][grouping_option][.precision][type]
(1) year = 2001
"Xawang在 {} 年出生".format(year) -- 'Xawang在 2001 年出生'
(2){}相当于元组中元素,可以用下标,也可以用变量名(变量名必须加=)
"{0}, {0}, {1}, {name}, {hoby}".format("python","人工智能",name="小阿旺",hoby="python") -- 'python, python, 人工智能, 小阿旺, python'
(3)要想保留{},可以用双层的{}:
"{},{{}},{}".format(1,2) -- '1,{},2'
也可以直接用{}作参数:
"{},{}".format("{}","python") -- '{},python'
1. align -- 对齐的方式
'<' -- 强制字符串在可用空间内左对齐(默认)
'>' -- 强制字符串在可用空间内右对齐
'=' -- 强制将填充放置在符号(如果有)之后但在数字之前的位置(这适用于以"+000000120"的形式打印字符串)
'^' -- 强制字符串在可用空间内居中
*:
"{:^40}".format(520) -- ' 520 '
"{1:>10}{0:<10}".format(520,250) -- ' 250520 '
"{left:>10}{right:<10}".format(right=520,left=250) -- ' 250520 '
"{:8=10}".format(+520) -- '8888888520'
"{:8=10}".format(-520) -- '-888888520'
"{:010}".format(-520) -- '-0000000520'
2. 符号选项
'+' -- 正数前面添加正号(+),复数前面添加负号(-)
'-' -- 只有负数前面添加负号(-),默认行为
空格 -- 正数前面添加一个空格,负数在前面添加负号分(-)
*:
"{:+} {:}".format(520,-520) -- '+520 -520'
"{:0=+10}".format(520) -- '+000000520'
3. 千分位分隔符:','&'_'
"{:,}".format(1234) -- '1,234'
"{:_}".format(1234) -- '1_234'
*:位数不足的话,千分位分隔符是不显示的
4. 精度
对于[type]设置为'f'或'F'的浮点数来说,是限定小数点 后 显示多少个位数
对于[type]设置为'g'或‘G’的浮点数来说,是限定小数点 前后 一共显示多少位数
对于非数字类型来说,限定的是 最大字段 的大小
对于整数来说,则 不允许 使用[.precision]选项
*:
"{:.2f}".format(3.1415) -- '3.14'
"{:.2g}".format(3.1415) -- '3.1'
"{:.6}".format("I love China") -- 'I love'
"{:.2}".format(520) -- ValueError: Precision not allowed in integer format specifier
适用于整数
的类型
值 | 含义 |
---|---|
'b' | 将参数以二进制形式输出 |
'c' | 将参与以Unicode字符形式输出 |
'd' | 将参与以十进制形式输出 |
'o' | 将参数以八进制形式输出 |
'x' | 将参数以十六进制形式输出 |
'n' | 跟'd'类似,不同之处在于他会使用当前语言环境设置的分隔符插入到恰当的位置 |
'None' | 跟'd'一样 |
eg:
适用于浮点数
和复数
的类型
'e' | 将参数以科学计数法的形式输出(以字母'e'来标示指数,默认精度为6) |
'E' | 将参数已科学计数法形式输出(以字母'E'来标示指数,默认精度为6) |
'' | 将参数以定点表示的形式输出("不是数"用'nan'标示,无穷用'inf'标示,默认精度为6) |
'F' | 将参数以定点表示法的形式输出,"不是数"用'NAN'标示,无穷用'INF'标示,默认精度为6 |
'g' | 通用格式,小数以'f'形式输出,大数以'e'的形式输出 |
'G' | 通用格式,小数以'F'形式输出,大数以'E'的形式输出 |
'n' | 跟'g'类似,不同之处在于他会使用当前语言环境设置的分隔符插入到恰当的位置 |
'%' | 以百分比的形式输出(将数字乘以100并显示为定点表示法'f'的形式,后面附带一个百分号) |
None | 类似于'g',不同之处在于当使用定点表示法时,小数点后面将显示少一位;默认精度与给定值所需的精度一致 |
eg:
f-字符串 – f-string – 可以看作format()方法的一个语法糖
f字符串,就是将format方法的内容放在`:`前面:
f"{12343.1415:*^40_.2f}" -- '***************12_343.14****************'
year = 2001
f"小阿旺出生于{year}年" -- '小阿旺出生于2001年'
序列
列表元组字符串相互转换 – list()、tuple()、str()
1. list() -- 将元组或字符串转换成列表:
list("Xawang") -- ['X', 'a', 'w', 'a', 'n', 'g']
list((1,2,3,4,5)) -- [1, 2, 3, 4, 5]
2. tuple() -- 将列表或字符串转换成元组:
tuple("Xawang") -- ('X', 'a', 'w', 'a', 'n', 'g')
tuple([1,2,3,4,5]) -- (1, 2, 3, 4, 5)
3. str() -- 将列表或者元组转成字符串 -- 其实就是加一个引号:
str([1,2,3,4,5]) -- '[1, 2, 3, 4, 5]'
str((1,2,3,4,5)) -- '(1, 2, 3, 4, 5)'
min()和max()
min(iterable, *[,key, default])
min(arg1, arg2, *args[, key])
max(iterable, [,key, default])
max(arg1, arg2, *args[, key])
*:
s = [1,2,3,4,5]
min(s) -- 1
s = []
min(s,default="啥也没有,怎么找最小?") -- '啥也没有,怎么找最小?'
len() 和 sum()
len() -- 字符串长度,32位系统最大可承受范围2^31-1,64位系统2^63-1
sum() -- 求和
s = [0,0,4,5]
sum(s) -- 9
sum (s,start=100) -- 109
start表示从多少开始加
sorted() 和 reversed()
sorted(iterable[[, key=None][, reverse=False]]) -- 从小到大排序,返回新的列表。参数可以是任何序列
key传入的是函数名字,比如说传入len代表使用长度进行排序
*:
t = ["Apple","Banana","Book","puple","Pen"]
sorted(t) -- ['Apple', 'Banana', 'Book', 'Pen', 'puple']
sorted(t, key = len) -- ['Pen', 'Book', 'Apple', 'puple', 'Banana']
sorted(t,key = len, reverse = True) -- ['Banana', 'Apple', 'puple', 'Book', 'Pen']
reversed() -- 返回一个反向迭代器
*:
s = [1,2,5,8,0]
reversed(s) -- <list_reverseiterator object at 0x037D1AD8>
list(reversed((1,2,3,4,5))) -- [5, 4, 3, 2, 1]
list(reversed(range(0,10))) -- [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
list(reversed("Xawang")) -- ['g', 'n', 'a', 'w', 'a', 'X']
list(reversed([1,2,3,4,5])) -- [5, 4, 3, 2, 1]
all() 和 any()
all() -- 判断可迭代对象中是否所有值都为真
any() -- 判断可迭代对象中是否存在某个元素的值为真
*:
x = [1,1,0]
all(x) -- False
any(x) -- True
enumerate(iterable[, start])
enumerate() -- 用于返回一个枚举对象,他的功能就是将可迭代对象中的每个元素及从0开始的序号共同构成一个二元组的列表
*:
seasons = ["Spring", "Summer", "Fall", "Winter"]
enumerate(seasons) -- <enumerate object at 0x03B612D0>
list(enumerate(seasons)) -- [(0, 'Spring'), (1, 'Summer'), (2, 'Fall'), (3, 'Winter')]
start 代表序号从几开始
*:
list(enumerate(seasons,10)) -- [(10, 'Spring'), (11, 'Summer'), (12, 'Fall'), (13, 'Winter')]
zip()
zip() -- 用于创建一个聚合多个可迭代对象的迭代器,它会将作为参数参入的每个可迭代对象的每个元素一次组合成元组,即第i个元组包含来自每个参数的第i个元素
*:
x = [1,2,3]
y = [4,5,6]
zipped = zip(x,y)
zipped -- <zip object at 0x01706B48>
list(zipped) -- [(1, 4), (2, 5), (3, 6)]
*:假如可迭代对象长度不一致,以最短的为准
z = "Xawang"
zipped = zip(x,y,z)
list(zipped) -- [(1, 4, 'X'), (2, 5, 'a'), (3, 6, 'w')]
*:假如不想丢掉任何一个元素,可以使用zip_longest()
import itertools
list(itertools.zip_longest(x,y,z))
[(1, 4, 'X'), (2, 5, 'a'), (3, 6, 'w'), (None, None, 'a'), (None, None, 'n'), (None, None, 'g')]
map(指定函数,可迭代对象)
map() -- 会根据提供的函数对指定的可迭代对象的每个元素进行运算,并将返回运算结果的迭代器
*:
list(map(ord,"XAwang")) -- [88, 65, 119, 97, 110, 103]
*:假如指定的函数序号多个参数,只需要添加对应的可迭代对象数量就可以啦
list(map(pow,[2,3,20],[5,2,3])) -- [32, 9, 8000]
*:假如可迭代对象长度不一致,按最短的算
filter(指定函数,可迭代对象)
filter() -- 会根据提供的函数对可迭代对象的每个元素进行运算,并将运算结果为真的元素以迭代器的形式返回
*:
list(filter(str.islower,"Xawang")) -- ['a', 'w', 'a', 'n', 'g']
迭代器 VS 可迭代对象
一个迭代器肯定是一个可迭代对象
可迭代对象可以重复使用而迭代器是一次性的
eg:
mapped = map(ord,"Xawang")
for each in mapped:
print(each,end=' ') -- 88 97 119 97 110 103
list(mapped) -- []
iter()
iter() -- 将可迭代对象转换成迭代器
*:
x = [1,2,3,4,5]
y = iter(x)
type(x) -- <class 'list'>
type(y) -- <class 'list_iterator'>
next(iterator[, default])
next() -- 将迭代器中的每个元素挨个提取出来
*:
next(y) -- 1
next(y) -- 2
next(y) -- 3
next(y) -- 4
next(y) -- 5
next(y) -- StopIteration
*:
z = iter([1,2])
next(z,"没啦,已经被你掏空啦!") -- 1
next(z,"没啦,已经被你掏空啦!") -- 2
next(z,"没啦,已经被你掏空啦!") -- '没啦,已经被你掏空啦!'
字典 – dict
- python唯一实现了映射关系的内置类型
破译摩斯密码:
# 摩斯密码表
c_table = [".-","-...","-.-.","-..",".","..-.","--.","....",
"..",".---","-.-",".-..","--","-.","---",".--.",
"--.-",".-.","...","-","..-","...-",".--","-..-",
"-.--","--..",".----","..---","...--","....-",".....",
"-....","--...","---..","----.","-----"]
# 莫斯明文表
d_table = ["A","B","C","D","E","F","G","H","I","J","K","L","M",
"N","O","P","Q","R","S","T","U","V","W","X","Y","Z",
"1","2","3","4","5","6","7","8","9","0"]
code = input("请输入摩斯密码:\n")
split_code = code.split()
result = [d_table[c_table.index(each)] for each in split_code]
print(result)
"""若是换成一个表的"""
table = ['.-', 'A', '-...', 'B', '-.-.', 'C', '-..', 'D', '.', 'E',
'..-.', 'F', '--.', 'G', '....', 'H', '..', 'I', '.---', 'J',
-'-.-', 'K', '.-..', 'L', '--', 'M', '-.', 'N', '---', 'O',
'.--.', 'P', '--.-', 'Q', '.-.', 'R', '...', 'S', '-', 'T',
'..-', 'U', '...-', 'V', '.--', 'W', '-..-', 'X', '-.--',
'Y', '--..', 'Z', '.----', '1', '..---', '2', '...--', '3',
'....-', '4', '.....', '5', '-....', '6', '--...', '7',
'---..', '8', '----.', '9', '-----', '0']
code = input("请输入摩斯密码:\n")
split_code = code.split()
result = [table[table.index(each) + 1] for each in split_code]
print(result)
"""使用字典"""
table = {'.-': 'A', '-...': 'B', '-.-.': 'C', '-..': 'D',
'.': 'E', '..-.': 'F', '--.': 'G', '....': 'H',
'..': 'I', '.---': 'J', '-.-': 'K', '.-..': 'L',
'--': 'M', '-.': 'N', '---': 'O', '.--.': 'P',
'--.-': 'Q', '.-.': 'R', '...': 'S', '-': 'T',
'..-': 'U', '...-': 'V', '.--': 'W', '-..-': 'X',
'-.--': 'Y', '--..': 'Z', '.----': '1', '..---': '2',
'...--': '3', '....-': '4', '.....': '5', '-....': '6',
'--...': '7', '---..': '8', '----.': '9', '-----', '0'}
code = input("请输入摩斯密码:\n")
split_code = code.split()
result = [table[each] for each in split_code]
print(result)
*: 在映射类型数据的获取上,字典的效率是要远远快于列表的
字典的创建
六种常见的创建方式:
1. 直接使用{:}将映射关系套牢
(1) a = {'吕布': '方天画戟', '关羽': '青龙偃月刀', '刘备': '刘baby'}
2. 使用dict函数
(2) b = dict(大="big",小="small") -- 键上面不可以加引号
(3) c = dict([("惊讶","amazing"),("害怕","head")])
(4) d = dict({'吕布': '方天画戟', '关羽': '青龙偃月刀', '刘备': '刘baby'})
(5) e = dict({'吕布': '方天画戟', '关羽': '青龙偃月刀'}, 刘备 = '刘baby')
(6) f = dict(zip(["吕布","关羽","刘备"],["口口布","关习习","刘Baby"]))
字典的方法
增
1. fromkeys(iterable[,values]) -- 使用iterable指定的可迭代对象创建一个新的字典,并将所有的值初始化为values参数的指定的值
d = dict.fromkeys("Fish",250)
d -- {'w': 250, 'a': 250, 'n': 250, 'g': 250}
d['c'] = 67
d -- {'w': 250, 'a': 250, 'n': 250, 'g': 250, 'c': 67}
删
1. pop(key[,default])
d.pop('c') -- 67 --- 返回的是被删除键的值
*:
删除不存在的键会抛出异常,可以指定default,这样就可以返回default啦
2. popitem() -- 返回被删除的键值对
*:
3.7之前随机删除一个键值对
3.7之后,删除的是最后一个加入字典的键值对
d.popitem() -- ('g', 250)
3. del -- 删除一个指定的键,也可以直接删除整个字典
del d["n"] -- {'w': 250, 'a': 250}
4. clear() -- 清空字典内容
d = dict.fromkeys("wang",250) -- {'w': 250, 'a': 250, 'n': 250, 'g': 250}
d.clear() -- {}
改
1. update([other]) -- 可以传入包含键值对的可迭代对象,也可以直接传入一个字典
*:
d.update({"a":97,"W":87}) -- {'W': 87, 'a': 97, 'n': None, 'g': None, 'c': 99}
d.update(n=110,g=103) -- {'W': 87, 'a': 97, 'n': 110, 'g': 103, 'c': 99}
查
1. get(key[, default])
*:d.get("C", "这里没有C")
2. set(key[, default]) -- 查找不到就添加进去
*:
d.setdefault("c") -- 99
d.setdefault("C",67) -- d -- {'W': 87, 'a': 97, 'n': 110, 'g': 103, 'c': 99, 'C': 67}
3. items() -- 获取字典键值对视图对象
4. keys() -- 获取字典的键视图对象
5. values() -- 获取字典的值视图对象
*:视图对象:
字典的动态视图,这就意味着当字典的内容发生改变的时候,视图对象的内容也会相应的跟着改变
嵌套
1. 字典嵌套字典
d = {"吕布":{"语文":99,"数学":88,"英语":77},"猪脚亮":{"语文":100,"数学":100,"英语":88}}
d -- {'吕布': {'语文': 99, '数学': 88, '英语': 77}, '猪脚亮': {'语文': 100, '数学': 100, '英语': 88}}
d["吕布"]["数学"] -- 88
2. 字典嵌套列表
d = {"吕布":[99,88,77],"猪脚亮":[100,100,88]}
d -- {'吕布': [99, 88, 77], '猪脚亮': [100, 100, 88]}
d["吕布"][1] -- 88
字典推导式
d = {'W': 87, 'a': 97, 'n': 110, 'g': 103, 'c': 99}
b = {v:k for k,v in d.items()}
b -- {87: 'W', 97: 'a', 110: 'n', 103: 'g', 99: 'c'}
c = {v:k for v,k in d.items() if k > 100}
c -- {'n': 110, 'g': 103}
*:求出字符串的编码值:
d = {x:ord(x) for x in "Wangc"}
d -- {'W': 87, 'a': 97, 'n': 110, 'g': 103, 'c': 99}
*:初学者误区 -- 键唯一性
d = {x:y for x in [1,3,5] for y in [2,4,6]}
d -- {1: 6, 3: 6, 5: 6}
字典可使用的一些其他内容
1. copy() -- 对字典进行浅拷贝
2. len() -- 获取字典键值对数量
3. in -- 判断某个键是否存在于字典中
4. not in -- 判断某个键是否不存在于字典中
5. list() -- 获取字典中所有的键组成的列表
*:
list(d) -- ['W', 'a', 'n', 'g', 'c']
list(d.values()) -- [87, 97, 110, 103, 99]
6. iter() -- 将字典的键构成一个迭代器
7. reversed() -- 3.8之后可以对字典中的内容进行逆向操作
集合
- 无序不重复
集合创建
1. 在{}中放入元素
s = {"wangc","python"} -- {'wangc', 'python'}
2. 集合推导式
s = {s for s in "python"} -- {'p', 'o', 'n', 'y', 'h', 't'}
3. 类型构造器
set("python") -- {'p', 'o', 'n', 'y', 'h', 't'}
- 可以使用
in
和not in
;但不能使用索引 - 可以利用不重复的特性,快速实现去重的目的
set([1,1,1,1,1,2,3,4]) -- {1,2,3,4}
- 判断列表元素是否唯一
s = [1,1,1,12,3,4]
len(s) == len(set(s)) -- False
集合方法
1. s.copy() -- 浅拷贝
*:
s = set("python")
t = s.copy() -- {'p', 'y', 'o', 'h', 't', 'n'}
2. s.isdisjoint(other) -- 交集为空,那么返回True,负责返回False
*:传入的不一定是集合,也可以是其他可迭代对象
s = set("Wangc")
s.isdisjoint(set("python")) -- False
s.isdisjoint("JAVA") -- True
3. s.idsubset(other) -- 如果集合s是other容器的子集,那么返回True
*:
s.issubset("Xiao Wangc") -- True
4. s.issuperset(other) -- 如果s集合时other容器的超集,那么返回True
*:
s.issuperset("Wang") -- True
5. s.union(*others) -- 返回一个新集合, s∪others
*:
s.union({1,2,3}) -- {1, 2, 3, 'W', 'a', 'g', 'c', 'n'}
s.union("python",{1,2,3}) -- {1, 2, 3, 'n', 'W', 'g', 't', 'p', 'o', 'y', 'c', 'h', 'a'}
6. s.intersection(*others) -- 返回一个新集合,s∩others
*:
s.intersection("Wang") -- {'W', 'g', 'a', 'n'}
s.intersection("Wang","python") -- {'n'}
7. s.difference(*others) -- 返回新集合,存在于s,但不存在于others -- s - s∩others
*:
s.difference("Wang") -- {'c'}
s.difference("wang","python") -- {'W', 'c'}
8. s.symmetric_difference(other) -- 返回新集合,对称差集,排除s与others交集之后所有元素 -- s∪others - s∩others
*:
s.symmetric_difference("python") -- {'p', 'o', 'c', 'y', 'W', 'g', 'h', 't', 'a'}
8种常见操作对应的运算符
<=
真子集<
子集>=
真超集>
超集|
并集&
交集-
差集^
对称差集
不可变集合 – frozenset
适用于set的方法
1. update(*others) -- 使用others指定的值更新集合
2. intersection_update(*others) -- 交集
3. difference_update(*others) -- 差集
4. symmetric_difference_update(other) -- 对称差集
5. add(elem) -- 单纯的往集合里面添加元素
*注:
与update方法区别:update是将字符串拆开每个字符都作为一个元素,add是将整个字符串作为一个元素
6. remove(elem) -- 删除指定元素,指定元素不存在抛出异常
7. discard(elem) -- 删除指定元素,指定元素不存在静默处理
8. pop() -- 随机删除一个元素
9. clear() -- 将集合清空
可哈希
只有可哈希的对象才有资格作为字典的键,或者集合的元素
hash(object) -- 获取对象的哈希值
*:
整数的哈希值,永远是它本身;值相等的数哈希值也相等(1 == 1.0)
大多数不可变的对象都是可哈希的,可变的对象是不可哈希的
使用集合使效率提高
- 使用集合进行查找要比列表快很多
import random
import timeit
haystack = [random.randint(1, 10000000) for i in range(10000000)]
needles = [random.randint(1, 1000) for j in range(1000)]
# 请在此处添加一行代码,使得查找效率提高 10000 倍以上。
haystack, needles = frozenset(haystack), frozenset(needles)
def find():
found = 0
for each in needles:
if each in haystack:
found += 1
print(f"一共找到{found}个匹配。")
t = timeit.repeat(stmt='find()', setup='from __main__ import find', repeat=1, number=1)
print(f"查找过程一共消耗{t}秒。")
函数
- 最大程度减少代码的重用,减少冗余的代码。
- 将不同功能的代码,进行封装、分解,降低结构的复杂度,提高代码的可读性。
创建和调用函数
创建:
def 函数名():
函数体
调用:
函数名()
空函数:
def myfunc():
pass
无参函数:
def myfunc():
for i in range(3):
print("I love python")
有参函数:
def myfunc(name):
for i in range(3):
print(f"I love {name}")
多个参数:
def myfunc(name, times):
for i in range(times):
print(f"I love {name}.")
函数返回值:
- 使用
return
关键字返回内容 - 不加
return
:函数默认返回None
*:定义一个除法函数,返回运算结果
def div(x, y):
if y == 0:
return "除数不能为0嗷!"
return x / y
函数的参数
位置参数:
- 根据形参的位置确定
def myfunc(s, vt, o):
return "".join((o, vt, s))
关键字参数:
形参名=实参
注:
- 假如位置参数和关键字参数同时使用,位置参数只能写在前面
默认参数:
- 指定默认参数,在不传入实参的情况下使用默认参数
- 默认参数只能放在最后
def myfunc(name='小阿旺'):
print(f"name = {name}")
def myfunc(a, b="b", c="c"):
return [a,b,c]
'/'
左边的只能使用位置参数
自定义函数'/'
依旧有效
def abc(a, /, b, c):
print(a, b, c)
'*'
右侧只能使用关键字参数
def abc(a, *, b, c):
print(a, b, c)
收集参数:
- 在参数的前面加一个
*
1.
def myfunc(*args):
print("有{}个参数".format(len(args)))
print(f"第2个参数是:{args[1]}")
myfunc(1,2,3,4,5,6)
*: 有6个参数
第2个参数是:2
2.
def myfunc(*args):
print(args)
myfunc(1,2,3,4,5,6) -- (1, 2, 3, 4, 5, 6)
3.
def myfunc():
return 1,2,3
x, y, z = myfunc()
*:
x -- 1
y -- 2
z -- 3
- 通过
*
打包,将多个参数打包到一个元组里面
收集参数,写在前面的话,后面其他的参数,只能使用关键字参数
收集参数除了可以将参数打包成元组外还可以将参数打包成字典
def myfunc(**kwargs):
print(kwargs)
将收集参数,打包成元组和字典的方式一起使用
def myfunc(a, *b, **c):
print(a, b, c)
解包参数
- 在形参上使用 – 参数的打包
- 在实参上使用 – 解包参数
args = (1,2,3,4)
def myfunc(a, b, c, d):
print(a, b, c, d)
*1:
myfunc(*args) -- 1 2 3 4
*2:
kwargs = {'a':1, 'b':2, 'c':3, 'd':4}
myfunc(**kwargs) -- 1 2 3 4
作用域 – scope
- 局部作用域
- 全局作用域
- 一般根据位置而定
- 全局变量可以在函数内部使用
- 局部变量只能在函数内部使用
global
语句
- 声明一个变量为全局变量,这样就可以在函数内部对全局部变量进行修改
嵌套函数
- 嵌套在
funA()
里面的funB()
无法直接在外部被调用
def funA():
x = 520
def funB():
x = 888
print("In funB ,x =", x)
print("In funA, x=", x)
- 在
funA()
里面直接调用funB()
def funA():
x = 520
def funB():
x = 888
print("In funB, x =", x)
funB()
print("In funA, x =", x)
nonlocal
语句
- 在内部函数去修改外部函数的变量
def funA():
x = 520
def funB():
nonlocal x
x = 888
print("In funB, x =", x)
funB()
print("In funA, x =", x)
LEGB
规则 – Local Enclosed Global Build-In
局部
>嵌套函数的外层作用域
>全局
>内置
闭包 – closure
- 在一个外函数中定义了一个内函数,内函数里运用了外函数的临时变量,并且外函数的返回值是内函数的引用。这样就构成了一个闭包。
- 外函数的变量可以被内函数保存
*:案例一
def funA():
x = 888
def funB():
print(x)
return funB
*:案例二:
def power(exp):
def exp_of(base):
return base ** exp
return exp_of
*:案例三:
def outer():
x = 0
y = 0
def inner(x1, y1):
nonlocal x, y
x += x1
y += y1
print(f"现在,x = {x}, y = {y}")
return inner
案例:位置移动小游戏
origin = (0, 0) # 这个是原点
legal_x = [-100, 100] # 限定x轴坐标范围
legal_y = [-100, 100] # 限定y轴坐标范围
def create(pos_x=0, pos_y=0):
def moving(direction, step):
nonlocal pos_x, pos_y
new_x = pos_x + direction[0] * step
new_y = pos_y + direction[1] * step
if new_x < legal_x[0]:
pos_x = legal_x[0] - (new_x - legal_x[0])
elif new_x > legal_x[1]:
pos_x = legal_x[1] - (new_x - legal_x[1])
else:
pos_x = new_x
if new_y < legal_y[0]:
pos_y = legal_y[0] - (new_y - legal_y[0])
elif new_y > legal_y[1]:
pos_y = legal_y[1] - (new_y - legal_y[1])
else:
pos_y = new_y
return pos_x, pos_y
return moving
move = create()
print("向右移动20步后,位置是:", move([1,0], 20))
print("向上移动120步后,位置是:", move([0, 1], 120))
print("向右下角移动88步后,位置是:", move([1, 1], 88))
闭包核心技巧
1. 利用嵌套函数外层作用域具有记忆能力的特性,让数据保存在外层函数的参数或者变量中
2. 将内层函数作为返回值给返回,就可以从外部间接地调用到内层函数
装饰器–函数
函数用作参数
def myfunc():
print("正在调用myfunc...")
def report(func):
print("主人,我要开始调用函数啦...")
func()
print("主人,我调用完函数啦,快夸夸我^o^")
report(myfunc)
装饰器案例一:获取函数运行时间
import time
def time_master(func):
def call_func():
print("开始运行程序...")
start = time.time()
func()
stop = time.time()
print("结束运行程序...")
print(f"一共耗费了 {(stop - start):.6f} 秒。")
return call_func
# 装饰器语法糖
@time_master
def myfunc():
time.sleep(2)
print("Hello Wangc")
# 装饰器本来样子
# myfunc = time_master(myfunc)
myfunc()
# def time_master(func):
# print("开始运行程序...")
# start = time.time()
# func()
# stop = time.time()
# print("结束运行程序...")
# print(f"一共耗费了 {(stop - start):.6f} 秒。")
#
# def myfunc():
# time.sleep(2)
# print("Hello Wangc")
#
# time_master(myfunc)
装饰器案例二:多运算
- 同时使用多个装饰器
- 装饰器使用顺序:最下面的先被执行,从下往上依次执行
def add(func):
def inner():
x = func()
return x + 1
return inner
def square(func):
def inner():
x = func()
return x * x
return inner
def cube(func):
def inner():
x = func()
return x * x * x
return inner
@add
@square
@cube
def test():
return 2
print(test())
给装饰器传递参数
- 直接为最外层函数传参
import time
def logger(msg):
def time_master(func):
def call_func():
start = time.time()
func()
stop = time.time()
print(f"[{msg}一共耗费了 {stop - start:.4f} 秒。]")
return call_func
return time_master
@logger('A')
def funA():
time.sleep(1)
print("funA正在被调用...")
@logger('B')
def funB():
time.sleep(1)
print("funB正在被调用...")
# funA = logger('A')(funA)
# funB = logger('B')(funB)
funA()
funB()
lambda
匿名函数
-
lambda表达式:
lambda arg1, arg2, arg3, ... argN : expression
-
lambda表达式原本样貌:
def <lambda> (arg1, arg2, arg3, ... argN):
return expression
-
只能写一行,无法写多行代码
-
lambda
是关键字,表示匿名函数
lambda
案例
# 正常定义一个求平方的函数
def squareX(x):
return x * x
print(squareX(2))
# 使用lambda表达式定义一个求平方函数
squareY = lambda y: y * y
print(squareY(2))
# 将lambda表达式与列表相结合
m = [lambda x: x * x, 2, 3]
print(m[0](m[1]))
print(m[0](m[2]))
# 将lambda表达式作为map函数的参数
print(list(map(lambda x: ord(x) + 10, "wangc")))
# lambda做map参数的实现原理
def none_ord(x):
return ord(x) + 10
mapped = map(none_ord, "wangc")
print(list(mapped))
# 作为filter的参数
print(list(filter(lambda x: x % 2, range(10))))
生成器函数 – generator
- 用
yield
代替return
- 每次调用生成器提供一个数据
案例:只提供一个数据
def counter():
i = 0
while i <= 5:
yield i
i += 1
for j in counter():
print(j, end=' ')
c = counter()
print(c)
案例:斐波那契数列
# 正常借助for循环和列表实现
def fib():
fib_list = [0, 1]
for i in range(1, 10):
fib_list.append(fib_list[i] + fib_list[i - 1])
return fib_list
# 使用生成器实现
def fibonacci():
flag = 0
back1, back2 = 0, 1
while flag <= 10:
flag += 1
yield back1
back1, back2 = back2, back2 + back1
if __name__ == '__main__':
print("列表实现:")
print(fib())
print("生成器实现:")
f = fibonacci()
for each in f:
print(each, end=" ")
生成器表达式
t = (i ** 2 for i in range(10))
print(next(t))
print(next(t))
print(next(t))
print(next(t))
for i in t:
print(i, end=' ')
和列表推导式区别:
列表推导式直接将结果生成一个列表
生成器表达式一次只给一个结果
递归
import timeit
"""函数自身调用自身的一个过程"""
def funA(i):
if i > 0:
print("递归")
funA(i - 1)
# print(funA(5))
# 实现阶乘
def factorial_iter(n):
result = n
for i in range(1, n):
result = result * i
return result
print(factorial_iter(5))
# 递归实现
def factorial_recursion(n):
if n == 1:
return 1
else:
return n * factorial_recursion(n - 1)
print(factorial_recursion(5))
# 斐波那契数列
def fib(n):
a = 1
b = 1
c = 1
while n > 2:
c = a + b
a = b
b = c
n -= 1
return c
print(fib(12))
# 递归实现
def fib_recur(n):
if n == 1 or n == 2:
return 1
else:
return fib_recur(n - 1) + fib_recur(n - 2)
print(fib_recur(12))
if __name__ == '__main__':
print("n=1,000,000时,fib运行所用时间:",timeit.timeit("fib(1000000)", "from __main__ import fib", number=1))
print("n=37时,fib_recur运行所用时间:",timeit.timeit("fib_recur(37)", "from __main__ import fib_recur", number=1))
递归应用 – 汉诺塔
n = int(input("请输入汉诺塔层数:"))
# n层汉诺塔需要的移动次数
def fun(n):
if n == 1:
return 1
else:
return 2 * fun(n - 1) + 1
print(fun(n))
# n层汉诺塔的移动步骤
def hanoi(n, x, y, z):
if n == 1:
print(x, "-->", z) # 如果只有一层,直接将金片从 x 移动到 z
else:
hanoi(n - 1, x, z, y) # 将 x 上的 n-1 个金片移动到 y
print(x, '-->', z) # 将 x 上的第 n 个金片移动到 z
hanoi(n - 1, y, x, z) # 将 y 上的 n-1 个金片移动到 z
hanoi(n, 'A', 'B', 'C')
# 前序输出 -- 左中右
函数文档注释
函数文档
- help() – 快速查看函数文档
-
函数文档的创建
def exchange(dollar, rate=7.15):
"""
功能:汇率的转换, 美元 --> 人民币
:param dollar: 美元数量
:param rate: 汇率, 默认值是 7.15 (2023-07-26)
:return: 人民币数量
"""
return dollar * rate
print(exchange(20))
help(exchange)
类型注释
- str 与 : int 为类型注释,不会对实际要输入的类型产生影响
def times(s: str, n: int) -> str:
return s * n
print(times("apple", 5))
print(times(5, 5))
# appleappleappleappleapple
# 25
- 在使用类型注释时,设置默认参数
def times(s: str = "apple", n: int = 5) -> str:
return s * n
- 期待的映射类型
def times(s: "list[int]", n: int = 5) -> list:
return s * n
def times(s: "dict[str, int]", n: int = 5) -> list:
return list(s.keys()) * n
print(times({'A': 1, 'B': 2}, 2))
# ['A', 'B', 'A', 'B']
内省
- 在程序运行的时候,能够进行自我检测的一种机制
- python通过一些特殊的属性
- 想知道一个函数的名字
print(times.__name__)
- 想知道函数的类型注释
print(times.__annotations__)
- 想知道函数的文档注释
print(exchange.__doc__)