#单行注释
'''
多行注释
'''
"""
多行注释
"""
特殊注释1:为了能够在linux下以./+文件名.py方式运行代码,需要在py文件中添加
#!/usr/bin/python
#!/usr/bin/env python
特殊注释2:以什么编码方式解析文件,python2默认不支持中文,需要加上;python3直接中文支持,不需要加
# encoding=utf-8
# coding=utf-8
正规的Python推荐写法:# _*_ coding:utf-8 _*_
字符编码规定了:
(1)按照怎样的规范把字符转换成数字?
(2)按照怎样的方式存储数字(如: 用多少个字节?)
在将字符存储到内存时就会面临两个问题:
(1)编码:按照什么规范将字符转换成0-1二进制进行存储
(2)解码:按照什么规范将存储的0-1二进制转换成字符
正是解码和编码这两个过程不统一,才会导致读取的文件发生乱码。
为什么有这么多字符码?
1. 怎样定义变量:
a = 2
print(a)#输出 2
a,b = 1,2
print(a,b) #输出:1 2
a = b = 2
print(a,b)输出:2 2
2. 为什么要产生变量
1. 为什么要区分数据类型?
#例如,根据不通的数据类型进行不同的+操作
print(6+6)#输出:12
print("6"+"6")#输出:66
2.数据类型:
| 常用数据类型 | 例子 |
|---|---|
| Numbers(数值类型) | i n t 、 l o n g 、 f l o a t 、 c o m p l e x int、long、float、complex int、long、float、complex |
| Bool(布尔类型) | T r u e 、 F a l s e True、False True、False |
| String(字符串) | ′ s t r ′ 、 ′ ′ ′ s t r ′ ′ ′ 、 " s t r " 、 " " " s t r " " " 'str'、'''str'''、"str"、"""str""" ′str′、′′′str′′′、"str"、"""str""" |
| List(列表) | [ 1 , 2 , 3 ] [1,2,3] [1,2,3] |
| Set(集合) | [ s e t ( [ 1 , 2 ] ) [set([1, 2]) [set([1,2]) |
| Tuple(元组) | ( " 小王 " , 18 ) ) ("小王", 18)) ("小王",18)) |
| Dictory(字典) | n a m e : " 王顺子 " , a g e : 18 {name: "王顺子", age: 18} name:"王顺子",age:18 |
| NoneType(空类型) | N o n e None None |
P y t h o n 3 Python3 Python3无 l o n g long long类型,会自动根据数值大小,调整 i n t int int字节长度
3. 查看类型:
t
y
p
e
(
)
type()
type()
num = 6
print(type(num))#
这个类型是属于数值的,不是属于变量的。type会根据num的引用找到数值所在地,然后输出该数值的类型。
1. 概念:
将一个数据转换成指定的类型, 方便处理
2.应用场景举例:
银行存钱:
money = input("输入你要存储的金额")
total_money = 20+ money
此时就会报错:
TypeError: unsupported operand type(s) for +: 'int' and 'str'
因为 i n t int int类型的20不能和 S t r i n g String String类型的 m o n e y money money进行相加。
因此,需要进行数据转换。
3.方式:
将
m
o
n
e
y
money
money改成
i
n
t
int
int类型:
i
n
t
(
)
int()
int()方法
money = input("输入你要存储的金额")
total_money = 20+ int(money)
其余类型转化函数如下:

4. 面试补充 \color{red}{4.面试补充} 4.面试补充
1.算数运算符:
| 算数运算符 | 名称 |
|---|---|
| + | 加法运算符 |
| - | 减法运算符 |
| * | 乘法运算符 |
| ** | 幂运算符 |
| / | 除法运算符 |
| // | 整除运算符 |
| % | 求模运算符 |
| = | 赋值运算符 |
扩展:
整除和求余的应用场景:
假设存在一个数组,序号如下所示。
以序号 9 9 9的元素为例子,
获取 9 9 9的行号:9//4=2,即第2行
获取 9 9 9的列号:9%4=1,即第1列
2.复合运算符:
| 复合运算符 | |
|---|---|
| += | a + = b → a = a + b a+=b→a=a+b a+=b→a=a+b |
| -= | a − = b → a = a − b a-=b→a=a-b a−=b→a=a−b |
| *= | a ∗ = b → a = a ∗ b a*=b→a=a*b a∗=b→a=a∗b |
| **= | a ∗ ∗ = b → a = a ∗ ∗ b a**=b→a=a**b a∗∗=b→a=a∗∗b |
| /= | a / = b → a = a / b a/=b→a=a/b a/=b→a=a/b |
| //= | a / / = b → a = a / / b a//=b→a=a//b a//=b→a=a//b |
| %= | a % = b → a = a % b a\%=b→a=a\%b a%=b→a=a%b |
3.比较运算符:
| 比较运算符 | |
|---|---|
| > | 是否大于 |
| < | 是否小于 |
| != | 是否不等于 |
| <> | P y t h o n 2. Python 2. Python2.的不等于, 3.0 3.0 3.0版本不支持 |
| >= | 是否大于等于 |
| <= | 是否小于等于 |
| == | 是否等于 |
| is | 对比唯一标识 |
| 链状比较运算符 | 10 < a < = 66 1010<a<=66 |
关于 i s : is: is:
这里对比的是唯一标识,
如,赋值语句 a = 10 a=10 a=10,此时会开辟一段存储空间,并将存储空间的唯一标识返回给 a a a。
i s is is比较的就是上述的唯一标识,可以理解为存储地址。
如下图:
这里 a a a和 b b b相等的原因是,它们值相等,为了提高性能, P y t h o n Python Python将这两个变量分配了相同的唯一标识
==比较的是只,is比较的是唯一标识
4.逻辑运算符:
| 逻辑运算符 | |
|---|---|
| not | 非,取反 |
| and | 与(二元运算符) |
| or | 是否不等于 |
非布尔类型的值, 如果作为真假来判定, 一般都是非零即真, 非空即真。
整个逻辑表达式的结果不一定只是 T r u e True True和 F a l s e False False。
print(3 and 0) #输出 0
#上式bool值为False,输出为0标识走到0这才判断为False的
if 3 or 1:
print(3 or 1)#输出为3
#上式bool值为True,输出为3标识走到3这就能判断为True
#上面的3为非空,也不是0,所以布尔值为True
#为空,布尔值为False
print(bool(""))#输出为False
1. python2中:
在
P
y
t
h
o
n
2
Python2
Python2中有两个输入函数:
result = raw_input('提示信息')result = input('提示信息')例子:
# _*_ coding:utf-8 _*_
#Python2环境下
result = raw_input('提示信息')#输入:1+1
print type(result)#输出:
print result #输出:1+1
result = input('提示信息')#输入:1+1
print type(result)#输出:
print result #输出:2
#python2中会将输入的部分不做处理的赋值给左部变量
result = input('提示信息')#输入:a+b
print result #报错:name 'abc' is not defined
#报错的原因是:result = a+b了,不做处理赋值给左部
#想输入字符串:
result = raw_input('提示信息')#输入:"a+b"
print type(result)#输出:
print result #输出:a+b
2. python3中
在
P
y
t
h
o
n
3
Python3
Python3中有一个输入函数:
result = input('提示信息')
Python2:
print xxxprint 123 #输出:123
Python3:
print(values,sep,end,file,flush)
file=sys.stdoutf = open("xxx", "w");file=f使用场景:
输出一个值:
print 值print(值)输出一个变量:
print 变量名print(变量名)输出多个变量:
print 变量名1, 变量名2print(变量名1, 变量名2)格式化输出:
print "随意内容...占位符1, ... , 占位符2, ..."%(变量1, 变量2)print "我的名字是%s,年龄是%d"%("小王",12)print "我的名字是{0},年龄是{1}".format("小王",12)print("随意内容...占位符1, ... , 占位符2, ..."%(变量1, 变量2))

输出到文件中:
file = open("test.txt","w")print>>file,"who am i"file = open("test.txt","w")print("who am i",file=file)输出不自动换行
print a.print("hello",end="")输出的各个数据,使用分割符分割
print("hello","world",sep="---")
格式:
%[(name)][flags][width][.precision]typecode
中括号[]包含的部分表示是可选的,即可省略的。
(name):用于选择指定的名称对应的值
即根据key获取具体值;
print("数学分数是%(math)d,英语分数是%(Eng)d" % {"Eng":60,"math":59})
width:表示显示宽度
print("%4d" % (59))
flags:
空:表示右对齐
- :表示左对齐
print("%-4d|" % (59))
空格:表示在左侧填充一个空格
print("|% d" % (59))
0:表示使用0填充
print("%04d" % (59))
.precision:表示小数点后精度
print("%.2f" % (59.99999))
typeCode:
i/d
将整数、浮点数转换成十进制表示,并将其格式化到指定位置
- 将二进制转成十进制输出:
print("%d" % (0b1001))
o
将整数转换成八进制表示,并将其格式化到指定位置
x
将整数转换成十六进制表示,并将其格式化到指定位置
e/E
将整数、浮点数转换成科学计数法,并将其格式化到指定位置(e/E输出的是小写/大写的e/E)
print("%E" % (10000))
f/F
将整数、浮点数转换成浮点数表示,并将其格式化到指定位置(默认保留小数点后6位)
g/G
自动调整将整数、浮点数转换成浮点型或科学计数法表示(超过6位数用科学计数法),并将其格式化到指定位置(如果是科学计数则是e/E;)
print("%g" % (100000)); print("%g" % 20)
c
将数字转换成其unicode对应的值,10进制范围为
0
<
=
i
<
=
1114111
0<=i<=1114111
0<=i<=1114111(py27则只支持0-255);
print("%c" % 26666)
特殊:%
想输出90%之类的加载值时,需要输入两个%,第一个%充当转义符
print("%d%%" % 30)
单分支判断:
格式:
if 条件:
当条件满足,执行语句
实例:
age=int(input("请输入年龄"))
if age>=18:
print("你已成年")
双分支判断:
格式:
if 条件:
条件满足时,执行语句
else:
条件不满足时,执行语句
实例:
age=int(input("请输入年龄"))
if age>=18:
print("你已成年")
else:
print("未满18岁")
练习案例:
根据分数区间, 打印出对应的级别
score = int(input("请输入成绩"))
if 90<=score<=100:
print("优秀")
if 80<=score<90:
print("良好")
if 60<=score<80:
print("及格")
if 0<=score<60:
print("不及格")
上述案例中,输入的成绩只会满足其中一个分支条件。但是在实际运行时,每个分支都会进行判断,导致效率低下。
可以考虑使用if嵌套:
格式:
if 条件1:
条件满足时,执行语句
else:
#执行条件2判断
if 条件2:
条件满足时,执行语句
else:
……
实例:
score = int(input("请输入成绩"))
if 90<=score<=100:
print("优秀")
else:
if 80<=score<90:
print("良好")
else:
if 60<=score<80:
print("及格")
else:
print("不及格")
多分支判断:
格式:
if 条件1:
满足条件1,执行语句
elif 条件2:
满足条件2,执行语句
else:
都不满足,执行语句
案例:
score = int(input("请输入成绩"))
if 90<=score<=100:
print("优秀")
elif 80<=score<90:
print("良好")
elif 60<=score<80:
print("及格")
else:
print("不及格")
注意
如下面的两个分支语句,其中的else处于不同的缩进状态;第一个分支语句的else属于分支2的if,第二个分支语句的else属于分支1的if。
if 分支1判断条件:
if 分支2判断条件:
执行语句
else:
执行语句
if 分支1判断条件:
if 分支2判断条件:
执行语句
else:
执行语句
使用场景:
while循环
格式:
while 条件:
条件满足时执行代码
流程图:

实例:
打印某句话10遍:
num = 0
while num<10:
num+=1
print(num,"打印10遍")
计算1-10数值的总和
num = ans = 0
while num<10:
num+=1
ans+=num
print(ans)
while else
格式:
while 条件:
满足条件时
else :
条件不满足时,执行的代码
流程图:

实例:
num = ans = 0
while num<10:
num+=1
ans+=num
else:
print(ans)#输出55
注意
使用场景:
语法:
for x in xxx:
循环语句
通常搭配range(n)函数使用,range(n)会生成0~n-1的整数列表
案例:
str = "abcdefg"
for s in str:
print(s)
'''
输出:
a
b
c
d
e
f
g
'''
for i in range(10):
print(i)
'''
输出:
0
1
2
3
4
5
6
7
8
9
'''
for与else连用:
格式:
for x in xxx:
条件满足时的执行代码
else:
条件不满足时执行的语句
案例:字符串反转:
str1 = "abcdefg"
str2 = ""
for s in str:
str2 = s+str2
else:
print(str2)#输出:gfedcba
循环打断,会对while和for与else的连用产生影响:
break:
打断本次循环, 跳出整个循环
如下,当i==2时执行break语句;break语句中断本次循环并跳出当前循环
for i in range(10):
if i==2:
break;
print(i)
'''
0
1
'''
注意:break只会跳出一层循环
for j in range(2):
for i in range(10):
if i==2:
break;
print(i)
'''
输出:
0
1
0
1
'''
continue:
结束本次循环, 继续执行下次循环
for i in range(10):
if i==2:
continue
print(i)
'''
输出:(没有2了)
0
1
3
4
5
6
7
8
9
'''
循环内嵌套循环和循环内嵌套if,其本质就是只要是代码,都能放在代码块的位置。
for x in xxx:
这个缩进开始就是一个代码块;
可以放if语句,也可以放循环语句
案例:打印1-100之间, 所有3的倍数
for i in range(1,101):
if i%3==0:
print(i)
案例:打印九九乘法表
外层循环每循环一次,内层循环就要循环一遍
for num in range(1,10):
for n in range(1,num+1):
print("%d * %d = %d" % (num,n,num*n),end='\t')
print("")
'''
1 * 1 = 1
2 * 1 = 2 2 * 2 = 4
3 * 1 = 3 3 * 2 = 6 3 * 3 = 9
4 * 1 = 4 4 * 2 = 8 4 * 3 = 12 4 * 4 = 16
5 * 1 = 5 5 * 2 = 10 5 * 3 = 15 5 * 4 = 20 5 * 5 = 25
6 * 1 = 6 6 * 2 = 12 6 * 3 = 18 6 * 4 = 24 6 * 5 = 30 6 * 6 = 36
7 * 1 = 7 7 * 2 = 14 7 * 3 = 21 7 * 4 = 28 7 * 5 = 35 7 * 6 = 42 7 * 7 = 49
8 * 1 = 8 8 * 2 = 16 8 * 3 = 24 8 * 4 = 32 8 * 5 = 40 8 * 6 = 48 8 * 7 = 56 8 * 8 = 64
9 * 1 = 9 9 * 2 = 18 9 * 3 = 27 9 * 4 = 36 9 * 5 = 45 9 * 6 = 54 9 * 7 = 63 9 * 8 = 72 9 * 9 = 81
'''
概念:
pass是空语句,不做任何事情,一般用做占位语句。
作用:
是为了保持程序结构的完整性
如下面代码,并没有想好年龄大于18和小于18时要进行什么操作,但是该程序的框架就是这样。为了避免运行报错,可以使用pass代替具体的操作,等后续在用具体操作替代pass。
age = 18
if age>=18:
pass
else:
pass
表现形式:
0b+二进制数0o+八进制数0x+十六进制数1.682e2常用操作:
内置数学函数: 内置数学函数: 内置数学函数:
abs(num)
返回数字的绝对值

max(num1, num2…)
返回序列中的最大元素

min(num1, num2…)
返回序列中的最小元素

round(num[, n])
四舍五入;n是可省参数,标识四舍五入的位数

pow(x, y)
返回 x 的 y次幂,即x**y

m a t h 函数模块 math函数模块 math函数模块
ceil(num)
上取整

floor(num)
下取整

sqrt(num)
开平方

log(x,base)
开平方

r a n d o m 模块的随机函数 random模块的随机函数 random模块的随机函数
m a t h 模块的三角函数 math模块的三角函数 math模块的三角函数
sin(x)
正弦,x是弧度
cos(x)
余弦,x是弧度
tan(x)
正切,x是弧度
asin(x)
反正弦,x是弧度
acos(x)
反余弦,x是弧度
atan(x)
反正切,x是弧度
degrees(x)
弧度 转换成 角度
radians(x)
角度 转换成 弧度
数学常量
数学常量
数学常量
math.pi

b o o l bool bool分为: T r u e True True和 F a l s e False False,布尔类型是 i n t int int类型的子类:

bool的False可以当做0与数值类型相加:

bool的True可以当作1与数值类型相加:

概念:
由单个字符组成的一个集合
形式:
非原始字符串:
'abc'"abc"'''abc'''"""abc"""
混合使用可以避免使用引号转义符
一般内容需要写成一行,跨行需要连行符\ 或者使用 小括号

三引号可以直接跨行书写,可用于注释
原始字符串:
(原始字符串内部不会识别转义符)
r'abc'r"abc"r'''abc'''r"""abc"""概念补充(转义符):
\(在行尾时) 续行符

\’ 单引号

\" 双引号

\n 换行

\t 横向制表符

字符串一般操作:
方式1:
s
t
r
+
s
t
r
2
str+str2
str+str2

方式2:
s
t
r
1
s
t
r
2
str1str2
str1str2

方式3:“xxx%sxxx”%(abc)

方式4:字符串乘法

字符串切片
概念:
获取一个字符串的某个片段
获取某个字符:name[下标]


获取一个字符型片段:name[起始:结束:步长]
获取范围:[起始,结束);起始包含,结束不包含
默认值:
获取顺序:


查找操作
l e n len len:

f i n d find find:
左开右闭
r f i n d rfind rfind

i n d e x index index
r i n d e x rindex rindex

转换
c o u n t count count:

r e p l a c e replace replace:

c a p i t a l i z e capitalize capitalize:

t i t l e title title:

l o w e r lower lower

u p p e r upper upper:

填充压缩
l j u s t ljust ljust:
长度只能为1), 将原字符串填充够指定长度
r j u s t rjust rjust:
长度只能为1), 将原字符串填充够指定长度
c e n t e r center center:
长度只能为1), 将原字符串填充够指定长度
l s t r i p lstrip lstrip:

r s t r i p rstrip rstrip:

分割拼接
s p l i t split split:
作用:将一个大的字符串分割成几个子字符串
语法:split(sep, maxsplit)
参数:
sep:分隔符
maxsplit:最大的分割次数(分割次数,而分割结果字符数);可省略, 有多少分割多少
返回值:
分割后的子字符串, 组成的列表(list 列表类型)
注意
并不会修改原字符串本身
实例:

p a r t i t i o n partition partition:

r p a r t i t i o n rpartition rpartition:

s p l i t l i n e s splitlines splitlines:

j o i n join join:

判定
i s a l p h a isalpha isalpha:

i s d i g i t isdigit isdigit:

i s a l n u m isalnum isalnum:

i s s p a c e isspace isspace:

s t a r t s w i t h startswith startswith:

e n d s w i t h endswith endswith:

补充
i
n
in
in
判定一个字符串, 是否被另外一个字符串包含

n
o
t
i
n
not\ in
not in
判定一个字符串, 是否不被另外一个字符串包含

列表概念:
有序的可变的元素集合
列表定义方式:
方式一:
[元素1,元素2,…]

方式二:
r a n g e ( s t o p ) range(stop) range(stop)

r a n g e ( s t a r t , s t o p , [ , s t e p ] ) range(start,stop,[,step]) range(start,stop,[,step])
参数:
start:开始的数值
stop:结束的数值
step:步长;可省参数。
实例:

注意:
为了防止生成的列表没有被使用,python3做了一些改变,不会立即生成列表。即使用的时候才会生成列表,第一个输出的nums的值range(0,10),此时未生成列表。
[表达式 for 变量 in 列表]


[表达式 for 变量 in 列表 if条件]

列表的嵌套
与java和c++的数组不同,python的列表可以存放不同的数据类型,存放的元素也可以是一个列表。

常规操作
增
a p p e n d append append:

i n s e r t insert insert:

e x t e n d extend extend:

乘法运算:

加法运算:

删:
d e l del del语句:

p o p pop pop:

r e m o v e remove remove:
作用:
移除列表中指定元素
语法:
l.remove(object)
参数:
object:需要被删除的元素
返回值:
None
注意:
会直接修改原数组
实例:

一个小坑:
注意循环内删除列表元素带来的坑
如列表元素为[2,2,4,2],要求删除列表中所有的2

使用循环的方式会出现错误,如上图。
原因:
遍历开始时遍历指针指向的索引为0的位置,因为是2所以将最左边的2删除。
之后遍历指针后移指向索引为1的位置,而此时因为列表首元素删除了,索引索引为1的位置是元素4,次吃不会发生删除。
继续遍历遍历指针指向索引为2的位置,此时索引2的地方是列表最后面的2,所以此时if语句成立删除最左边的2。此时遍历结束退出循环。
改:
使用name[index]赋值即可。

查:
获取单个元素:items[index]

获取元素索引:index()

获取指定元素个数:count()

获取多个元素:切片 items[start :end :step]

遍历:
方式1:根据元素进行遍历
for item in list:print(item)
方式2:根据索引进行遍历
for index in range(len(list)): print(index, list[index])

方式3:创建对应的枚举对象

方式4:使用迭代器进行遍历

迭代器:
概念:
迭代是访问集合元素的一种方式,按照某种顺序逐个访问集合中的每一项。
可迭代对象:
能够被迭代的对象, 称为可迭代对象

迭代器:
是可以记录遍历位置的对象。从第一个元素开始, 往后通过next()函数, 进行遍历。只能往后, 不能往前(有点类似获取数据库的next指针,依次向下获取)
为什么会产生迭代器?
迭代器的简单使用:
使用next()函数, 从迭代器中取出下一个对象, 从第1个元素开始。
额外操作:
判定:

比较:
c
m
p
(
)
cmp()
cmp():
python2.x中的内建函数。
如果比较的是列表, 则针对每个元素, 从左到右按字典序逐一比较
python3.x中直接使用比较符:>、<、=
针对每个元素, 从左到右逐一按字典序比较
实例:
第一个元素a相等,则比较第二个元素,c的字典序大于b所以list1大于list2

排序
方式1:

方式2:


乱序:
随机打乱一个列表

反转
方式一:

方式二:切片反转

元组概念:
有序的不可变的元素集合。
有序:可按索引查询元素
不可变:没有增删改操作
和列表的区别就是, 元组元素不能修改
定义方式:
一个元素的写法: ( 元素 , ) (元素,) (元素,)
a = (1)#会把括号识别成运算优先符
print(a,type(a))#输出:1
#正确写法
a=(1,)
print(a,type(a))#输出:(1,)
多个元素的写法:
a=(1,2,3)
print(a,type(a)) #输出:(1, 2, 3)
多个对象,以逗号隔开,默认为元组
a= 1 ,2 , "SZ"
print(a,type(a))#输出:(1, 2, 'SZ')
从列表转换成元组
内置函数:
t
u
p
l
e
(
s
e
q
)
tuple(seq)
tuple(seq)
l= [1 ,2 , "SZ"]
t = tuple(l)
print(t,type(t))#输出:(1, 2, 'SZ')
常用操作:
无增、删、改
获取单个元素: t u p l e [ i n d e x ] tuple[index] tuple[index]

获取多个元素:

额外操作:
获取:
t
u
p
l
e
.
c
o
u
n
t
(
i
t
e
m
)
tuple.count(item)
tuple.count(item):
统计元组中指定元素的个数(对象函数)

t
u
p
l
e
.
i
n
d
e
x
(
i
t
e
m
)
tuple.index(item)
tuple.index(item):
获取元组中指定元素的索引(对象函数)

l
e
n
(
t
u
p
)
len(tup)
len(tup):
返回元组中元素的个数(内置函数)

m
a
x
(
t
u
p
)
max(tup)
max(tup):
返回元组中元素最大的值(内置函数)

m
i
n
(
t
u
p
)
min(tup)
min(tup):
返回元组中元素最小的值(内置函数)
判定:

比较

拼接:
乘法:
(元素1, 元素2…) * int类型数值=(元素1, 元素2…, 元素1, 元素2…, …)

加法
(元素1, 元素2) + (元素a, 元素b)= (元素1, 元素2, 元素a, 元素b)

拆包:
实例:

a,b = 1,2,对于这条赋值语句,可以理解成将1,2构建成一个元组,再拆包分别赋值给a,b
应用:交换元素的值

字典概念:
无序的,可变的键值对集合
定义方式:
方式一: { k e y : v a l u e , k e y : v a l u e . . . } \{key: value, key: value...\} {key:value,key:value...}
d = {"name":"小王","age":18}
print(d,type(d))
#输出:{'name': '小王', 'age': 18}
方式二: f r o m k e y s ( s e q , v a l u e = N o n e ) fromkeys(seq, value=None) fromkeys(seq,value=None)
该方法是一个静态方法:即类和对象都可以调用
参数:
#类调用(推荐使用)
d = dict.fromkeys("abc",666)
print(d,type(d))
#输出:{'a': 666, 'b': 666, 'c': 666}
#对象调用(没必要再整一个字典来调用)
d = {}.fromkeys("abc",666)
print(d,type(d))
#输出:{'a': 666, 'b': 666, 'c': 666}
注意:
d = {"name":"小王","age":18,"name":"小红"}
print(d)#小红将前面的小王覆盖掉了
#输出:{'name': '小红', 'age': 18}
判断是否是可变类型的一个方法:
看下面的代码,首先将 a a a赋值为 10 10 10。这时候会在内存中开辟一块空间存放数字 10 10 10,并将这块空间的首地址返回给 a a a,所以当前 a a a指向存储数字 10 10 10的这块空间的地址。
之后将 a a a赋值为 20 20 20。这时候并不会去修改 a a a指向的这块地址空间。而是重新开辟一块地址空间去存储 20 20 20,将这块新开辟的地址空间返回给 a a a,则 a a a当下指向存储数字 20 20 20的空间地址。
入下面代码前后两次 i d ( a ) id(a) id(a)的值是不一样的,当出现这种情况,就可以说数值是一个不可变的类型。
a = 10
print(a,id(a))#输出:10 2363066772048
a=20
print(a,id(a))#输出:20 2363066772368
相反,如下代码。对列表进行插入操作后。 l l l并不会改变地址指向,插入的操作会在 l l l指向的地址上进行修改。
所以可以判断列表是一个可变类型。
l = [1,2,3]
print(l,id(l))#输出:[1, 2, 3] 2363180690560
l.append(4)
print(l,id(l))#输出:[1, 2, 3, 4] 2363180690560
字典的存储和查找流程:
Python的字典,采用哈希
h
a
s
h
hash
hash的方式实现
简单的存储过程:
简单的查找过程:
字典类型存在的意义:
常用操作:
增: d i c [ k e y ] = v a l u e dic[key] = value dic[key]=value
当key在原字典中不存在时, 即为新增操作
d = {"name":"小王"}
d["age"]=18#新增操作
print(d)#输出:{'name': '小王', 'age': 18}
删:
方式一: d e l d i c [ k e y ] del\ dic[key] del dic[key]
k e y key key必须要存在,否则会报 k e y E r r o r keyError keyError
d = {"name":"小王","age":18}
del d["name"]#删除操作
print(d)#{'age': 18}
方式二: d i c . p o p ( k e y [ , d e f a u l t ] ) dic.pop(key[, default]) dic.pop(key[,default])
d = {"name":"小王","age":18}
v = d.pop("name",666)#删除操作,并返回删除得value
print(v,d)#小王 {'age': 18}
d = {"name":"小王","age":18}
v = d.pop("A",666)#key不存在,则返回默认值666
print(v,d)#输出:666 {'name': '小王', 'age': 18}
方式三: d i c . p o p i t e m ( ) dic.popitem() dic.popitem()
删除字典的最后一个键值对,并以元组的形式返回该键值对。如果字典为空, 则报错
d = {"name":"小王","age":18}
v = d.popitem()#删除最后一个键值对:("age",18)
print(v,d)#('age', 18) {'name': '小王'}
方式四:
d
i
c
.
c
l
e
a
r
(
)
dic.clear()
dic.clear()
删除字典内所有键值对,并返回
N
o
n
e
None
None
d = {"name":"小王","age":18}
print(d.clear(),d)#输出:None {}
d
i
c
.
c
l
e
a
r
(
)
dic.clear()
dic.clear()与
d
e
l
del
del的区别:
d
i
c
.
c
l
e
a
r
(
)
dic.clear()
dic.clear()后字典对象本身还存在, 只不过内容被清空;而
d
e
l
del
del将该字典的内存给释放了,字典对象不存在了。
改:
只能改值,不能改key
d = {"name":"小王","age":18}
d["name"]="小红"
print(d)#{'name': '小红', 'age': 18}
d = {"name":"小王","age":18}
d.update({"name":"小红","age":20,"h":180})
print(d)#{'name': '小红', 'age': 20, 'h': 180}
查:
获取单个值:
d = {"name":"小王","age":18}
#方式一
print(d["name"])
#输出:小王
#方式二
print(d.get("name",666))
#输出:小王
print(d.get("h",666),d)#若没有该key,原字典不会新增这个键值对
#输出:666 {'name': '小王', 'age': 18}
#方式三
print(d.setdefault("name",666))
#输出:小王
print(d.setdefault("h",666),d)#若没有key,将其加入到字典中
#输出:666 {'name': '小王', 'age': 18, 'h': 666}
d = {"name":"小王","age":18}
#获取所有的值
print(d.values())#dict_values(['小王', 18])
#获取所有的键
print(d.keys())#dict_keys(['name', 'age'])
#获取字典的键值对
print(d.items())#dict_items([('name', '小王'), ('age', 18)])
注意:在Python3.x 中是上述三个函数返回的是 D i c t i o n a r y v i e w o b j e c t s Dictionary\ view\ objects Dictionary view objects类型,而不是一个列表。即比能通过索引值来获取元素,如下面的代码:
d = {"name":"小王","age":18}
#获取所有的值
v = d.values()
print(v[0])#报错:'dict_values' object is not subscriptable
D i c t i o n a r y v i e w o b j e c t s Dictionary\ view\ objects Dictionary view objects类型的好处:
d = {"name":"小王","age":18}
v = d.items()
print(v)#输出:dict_items([('name', '小王'), ('age', 18)])
#字典更新后,view objects会跟着发生改变
d["h"]=180
print(v)#输出:dict_items([('name', '小王'), ('age', 18), ('h', 180)])
#可以转成列表使用
l = list(v)
print(l[0])#输出:('name', '小王')
#可以使用for in进行遍历
for k,v in v: #注意:v是链表包含若干元组,索引可以使用拆包简化赋值
print(k,v)
'''
输出:
name 小王
age 18
h 180
'''
计算:
l
e
n
(
i
n
f
o
)
len(info)
len(info)
键值对的个数
d = {"name":"小王","age":18}
print(len(d))#输出:2
判定
d = {"name":"小王","age":18}
print("name" in d)#输出:True
集合概念:
无序的, 不可随机访问的, 不可重复的元素集合。
分为可变集合和非可变集合:
-
s
e
t
set
set:
可变集合,可以进行增删改操作
-
f
r
o
z
e
n
s
e
t
frozenset
frozenset:
不可变集合,创建之后,不可进行增删改
定义方式:
可变集合
s
e
t
set
set:
方式一: s = { 1 , 2 , 3 , 4 } s=\{1,2,3,4\} s={1,2,3,4}
s = {1,2,3,4}
print(s,type(s))#输出:{1, 2, 3, 4}
方式二: s = s e t ( i t e r a b l e ) s=set(iterable) s=set(iterable)
s1 = set([1,2,3])
print(s1,type(s1))#{1, 2, 3}
s2 = set({"name":"小王","age":18})
print(s2,type(s2))#{'age', 'name'}
方式三:集合推导式
s = set(x**2 for x in range(1, 10) if x % 2 == 0)s = {推导式}s1 = set(x**2 for x in range(1,10) if x%2 == 0)
print(s1,type(s1))#{16, 64, 4, 36}
s2 = {x**2 for x in range(1,5)}
print(s2,type(s2))#{16, 1, 4, 9}
不可变集合 f r o z e n s e t frozenset frozenset:
方式一: f s = f r o z e n s e t ( i t e r a b l e ) fs = frozenset(iterable) fs=frozenset(iterable)
方式二:集合推导式
s = frozenset(x**2 for x in range(1, 10) if x % 2 == 0)s = frozenset(x**2 for x in range(1,10) if x%2 == 0)
print(s,type(s))#frozenset({16, 64, 4, 36})
注意:
s1 = {1,2,1}
print(s1)#{1, 2}
s = {1,2,[1,2]}#报错unhashable type: 'list',因为列表不是可哈希的类型
常用操作:
单一集合操作:
可变集合:
1、增:
s
.
a
d
d
(
e
l
e
m
e
n
t
)
s.add(element)
s.add(element)
必须保证添加的元素是可哈希的值
s = {1,2,1}
s.add(3)
print(s)#输出:{1, 2, 3}
2、删:
方式一:
s
.
r
e
m
o
v
e
(
e
l
e
m
e
n
t
)
s.remove(element)
s.remove(element)
s = {1,2,3}
s.remove(3)
print(s)#{1, 2}
s.remove(31)#报错:KeyError
方式二: s . d i s c a r d ( e l e m e n t ) s.discard(element) s.discard(element)
s = {1,2,3}
s.discard(3)
print(s)#{1, 2}
s.discard(31)#不报错
方式三: s . p o p ( e l e m e n t ) s.pop(element) s.pop(element)
s = {1,2,3}
s.pop()
print(s)#{2, 3}
方式四:
s
.
c
l
e
a
r
(
)
s.clear()
s.clear()
清空一个集合中的所有元素
s = {1,2,3}
s.clear()
print(s)#输出:set()
改:
元素为不可变类型, 不能修改
查:
无法通过索引或key进行查询
方式一:通过 for in 进行遍历
s = {1,2,3}
for num in s:
print(num)
'''
输出:
1
2
3
'''
方式二:通过迭代器进行访问
s = {1,2,3}
itr = iter(s)
for i in range(len(s)):
print(next(itr))
'''
输出:
1
2
3
'''
不可变集合:
不能增删改
查:
方式一:通过 for in 进行遍历
s = frozenset({1,2,3})
for num in s:
print(num)
'''
输出:
1
2
3
'''
方式二:通过迭代器进行访问
s = frozenset({1,2,3})
itr = iter(s)
for i in range(len(s)):
print(next(itr))
'''
输出:
1
2
3
'''
集合之间操作:
交集:
方式一:
i
n
t
e
r
s
e
c
t
i
o
n
(
I
t
e
r
a
b
l
e
)
intersection(Iterable)
intersection(Iterable)
s1 = frozenset({1,2,3})
s2 = {3,4,5}
res1 = s1.intersection(s2)
print(res1)#frozenset({3})
res2 = s2.intersection(s1)
print(res2)#{3}
当是不可变集合调用函数时,返回的类型是不可变类型的集合。同理,当是可变集合调用函数时,返回的类型是可变类型的集合。
方式二:逻辑与 & \& &
s1 = frozenset({1,2,3})
s2 = {3,4,5}
res1 = s1&s2
print(res1)#frozenset({3})
res2 = s2&s1
print(res2)#{3}
返回的类型以最前面的类型为基准
方式三:
i
n
t
e
r
s
e
c
t
i
o
n
_
u
p
d
a
t
e
(
…
)
intersection\_update(…)
intersection_update(…)
上面的两种方式都不会改变原集合,而当前函数交集计算完毕后, 会再次赋值给原对象。因此,该函数只适用于可变集合。
s1 = frozenset({1,2,3})
s2 = {3,4,5}
s2.intersection_update(s1)
print(s2)#{3}
并集:
方式一:
u
n
i
o
n
(
)
union()
union()
返回并集
s1 = frozenset({1,2,3})
s2 = {3,4,5}
res = s1.union(s2)
print(res)#frozenset({1, 2, 3, 4, 5})
方式二:逻辑或
∣
|
∣
返回并集
s1 = frozenset({1,2,3})
s2 = {3,4,5}
res = s1|s2
print(res)#frozenset({1, 2, 3, 4, 5})
方式三:
u
p
d
a
t
e
(
)
update()
update()
会更新并集,不能通过不可变集合调用
s1 = frozenset({1,2,3})
s2 = {3,4,5}
s2.update(s1)
print(s2)#输出:{1, 2, 3, 4, 5}
差集
方式一:
d
i
f
f
e
r
e
n
c
e
(
)
difference()
difference()
s1 = frozenset({1,2,3})
s2 = {3,4,5}
res = s1.difference(s2)
print(res)#输出:frozenset({1, 2})
方式二:算术运算符减 − - −
s1 = frozenset({1,2,3})
s2 = {3,4,5}
res = s1-s2
print(res)#输出:frozenset({1, 2})
方式三: d i f f e r e n c e _ u p d a t e ( ) difference\_update() difference_update()
s1 = frozenset({1,2,3})
s2 = {3,4,5}
s2.difference_update(s1)
print(s2)#输出:{4, 5}
判定:
i
s
d
i
s
j
o
i
n
t
(
)
isdisjoint()
isdisjoint():判断两个集合是否不相交
s1 = frozenset({1,2,3})
s2 = {3,4,5}
print(s2.isdisjoint(s1))#输出:False
i s s u p e r s e t ( ) issuperset() issuperset():判断一个集合是否包含另一个集合
s1 = frozenset({1,2,3})
s2 = {3,2}
print(s1.issuperset(s2))#输出:True
i s s u b s e t ( ) issubset() issubset():判断一个集合是否是另一个集合的子集
s1 = frozenset({1,2,3})
s2 = {3,2}
print(s2.issubset(s1))#输出:True
概念:
简单理解, 就是写了一段代码实现了某个小功能; 然后把这些代码集中到一块, 起一个名字; 下一次就可以根据这个名字再次使用这个代码块, 这就是函数。
作用:
不使用函数的代码存在的问题:
函数分类:
函数定义:
def 函数名:
函数体
函数调用:
函数名()
例子:
#函数定义
def pFun():
print("打印函数")
#函数调用
pFun()#输出:打印函数
函数的参数: 函数的参数: 函数的参数:
单个参数:
使用场景:
需要动态的调整函数体中某一个处理信息,则可以以参数的形式接收到相关数据。
定义:
def 函数名(参数名称):
函数体(函数体中,可以直接以变量的方式使用该参数)
函数的调用:
函数名(参数值)
实例:
#函数定义
def pFun(text):
print("打印:",text)
#函数调用
pFun(123)#输出:打印: 123
形参和实参的概念:
- 上述函数定义中, "参数名称"即为形参;
- 在调用函数的时候, 传递的真实数据, 即为实参
多个参数:
场景:
需要动态的调整函数体中多个处理信息时,则可以以逗号做分割, 接收多个参数。
定义:
def 函数名(参数名称1,参数名称2,……):
函数体(函数体中,可以直接以变量的方式使用所有参数)
函数的调用:
#方式一:形参和实参一一对应
函数名(参数1,参数2,参数3,……)
#方式二:可以指明形参名称,称为"关键字参数",不需要严格按照顺序
函数名(参数名称1=参数1, 参数名称n = 参数n...)
实例:
#函数定义
def pFun(text1,text2):
print("打印:",text1,text2)
#函数调用方式一
pFun(123,456)#打印: 123 456
#函数调用方式二
pFun(text2=456,text1=123)#打印: 123 456
不定长参数:
场景:
如果函数体中, 需要处理的数据, 不确定长度,则可以以不定长参数的方式接收数据。
方式一:
定义:
在函数的参数前加一个*,表示将传入的参数变成元组,函数体以元组的方式使用该参数。
def 函数名(*args):
函数体(函数体中, 可以直接以元组变量的方式使用该参数)
使用:
函数名(参数1, 参数2, 参数3...)
实例:
#函数定义
def pFun(*args):
print(args,type(args))#(123, 456)
for t in args:
print(t,end=" ")#123 456
#函数调用
pFun(123,456)
方式二:
定义:
在函数的参数前加上**,表示将传入的参数变成字典类型,函数体以字典的方式使用该参数。
def 函数名(*args):
函数体(函数体中, 可以直接以元组变量的方式使用该参数)
使用:
函数名(参数名称1=参数1, 参数名称2=参数2...)
例子:
#函数定义
def pFun(**kwargs):
print(kwargs,type(kwargs))#{'text1': 123, 'text2': 456}
for d in kwargs.items():
print(d,end=" ")#('text1', 123) ('text2', 456)
#函数调用
pFun(text1=123,text2=456)
拆包与装包:
#函数定义
def pFun(**kwargs):
#拆包后的结果
print(kwargs)
#**装包,相当于a=x,b=y传到函数里
sum(**kwargs)
def sum(a,b):
print(a+b)
#函数调用
pFun(a=123,b=456)
缺省参数:
场景:
当我们使用一个函数的时候, 如果大多数情况下, 使用的某个数据是一个固定值, 或者属于主功能之外的小功能实现; 则可以使用默认值,这种参数, 称为"缺省参数"。
定义:
def 函数名(变量名1=默认值1, 变量名2=默认值2):
函数体(函数体中, 即使外界没有传递指定变量, 也可以使用, 只不过值是给定的默认值)
使用:
函数名(变量1, 变量2)#此处如果是缺省参数, 则可以不填写
例子:
#函数定义
def sum(a=2,b=3):
print(a+b)
#函数调用
sum()#5
sum(a=123,b=456)#579
值传递与引用传递:
值传递:
是指传递过来的, 是一个数据的副本;修改副本, 对原件没有任何影响。
引用传递:
是指传递过来的, 是一个变量的地址,通过地址, 可以操作同一份原件。
在Python当中, 你没得选, 只有引用传递(地址传递);如果数据类型是可变类型, 则可以改变原件,如果数据类型是不可变类型, 则不可以改变原件。
例子:
#函数定义
def change(num):
print(num,id(num))#10 1320407755344
num=20
print(num,id(num))#20 1320407755664
num=10
change(num)
print(num,id(num))#10 1320407755344
看上面的代码,首先定义了一个遍历num,此时python开辟了一块内存空间,存放数字10,并将地址返回给num变量,即num指向了存储数字10的地址。
然后将num作为change函数的参数,python只有引用传递,所有change中的第一个print输出的地址和全局变量num的地址是一样的。
进入change后,想要将num的值改成20,因为数值是一个不可变的类型,所以python为其重新开辟一块内存,存储数字20,并将地址返回给函数的num,可以看到函数的第二个print输出的地址发生了改变。
因为改变的是函数的num的地址指向,所以并不会改变外部全局num的地址指向,所以change运行后,也不会改变其值。
python的不可变类型有:数值、元组、字符串
python的可变数据类型:列表、字典、集合
当讲上述的num改成可变数据类型:
#函数定义
def change(l):
print(l,id(l))#[10] 1320492493184
l.append(20)
print(l,id(l))#[10, 20] 1320492493184
l=[10]
change(l)
print(l,id(l))#[10, 20] 1320492493184
可以看到,地址都没变过。
场景:
当我们通过某个函数, 处理好数据之后, 想要拿到处理的结果
语法:
def 函数():
函数体
return 数据
实例:
def sum(a,b):
return a+b
print(sum(1,2))#3
注意:
场景:
当我们编写三方函数, 为了方便他人使用, 就需要描述清楚我们所写的函数功能以及使用方式等信息。
定义格式:
直接在函数体的最上面, 添加三个双引号对注释
def 函数():
''' 这里写帮助信息 '''
查看描述: h e l p ( 函数名 ) help(函数名) help(函数名)
描述信息:
例子:
def caculate(a, b=1):
"""
计算两个数据的和, 以及差
:param a: 数值1, 数值类型, 不可选, 没有默认值
:param b: 数值2, 数值类型, 可选, 默认值: 1
:return: 返回的是计算的结果, 元组 : (和, 差)
"""
he = a + b
cha = a - b
return (he, cha)
help(caculate)
'''
显示内容
Help on function caculate in module __main__:
caculate(a, b=1)
计算两个数据的和, 以及差
:param a: 数值1, 数值类型, 不可选, 没有默认值
:param b: 数值2, 数值类型, 可选, 默认值: 1
:return: 返回的是计算的结果, 元组 : (和, 差)
'''
使用场景和概念:
当我们写一个参数比较多的函数时, 如果有些参数, 大部分场景下都是某一个固定值, 那么为了简化使用, 就可以创建一个新函数, 指定我们要使用的函数的某个参数, 为某个固定的值; 这个新函数就是"偏函数" 。
例子:
'''
一开始使用sum函数的时候,b的值大部分都是1,所以设置了默认值
'''
def sum(a, b=1):
return a+b
'''
后续使用时,可以不用每次都写b了
'''
print(sum(1))
'''
但是到某一刻,b的大部分情况变成了2;
此时可以自己创建一个函数来更改b的默认值
方便后续的使用,同时也不影响前面的代码
sum2就是一个偏函数
'''
def sum2(a,b=2):
return sum(a,b)
print(sum(2))
也可以借助Python的functools模块的partial函数来创建偏函数
语法:
import functools
newFunc = functools.partial(函数, 特定参数=偏爱值)
例子1:
def sum(a, b=1):
return a+b
import functools
newSum = functools.partial(sum,b=2)
print(newSum(1))
例子2:
'''
int(num)里面有一个base,默认是10,即将num按照10进制进行转换
但是在实际使用时会经常要把2进制的数进行转换,即将base=2,
为了避免每次调用都要写base=2,可以创建int()的偏函数
'''
import functools
newFun = functools.partial(int,base=2)
print(newFun("1010"))#10
概念:
当一个函数A的参数, 接收的又是另一个函数时, 则把这个函数A成为是"高阶函数"
例子1:sorted函数
l=[(1,2),(6,3),(7,1)]
def getKey(x):#高阶函数
return x[1]#按照第二个维度进行排序
sorted(l,key=getKey)
print(l)#[(1, 2), (6, 3), (7, 1)]
例子2:动态计算两个数据
def caculate(num1, num2, caculateFunc):
result = caculateFunc(num1, num2)
print(result)
def sum(a, b):
return a + b
def jianfa(a, b):
return a - b
caculate(6, 2, jianfa)#4
caculate(6, 2, sum)#8
概念:
是指一个函数内部, 它返回的数据是另外一个函数; 把这样的操作成为"返回函数"
例子:
def getFunc(flag):
# 1. 再次定义几个函数
def sum(a, b, c):
return a + b + c
def jian(a, b, c):
return a - b - c
# 2. 根据不同的flag值, 来返回不同的操作函数
if flag == "+":
#返回地是函数
return sum
elif flag == "-":
return jian
result = getFunc("-")
print(result, type(result))#.jian at 0x000001337544DAF0>
res = result(1, 3, 5)
print(res)#-7
概念:
也称为 “lambda函数”;顾名思义, 就是指没有名字的函数。
语法:
lambda 参数1, 参数2.. : 表达式
限制:
例子一:
res = lambda x,y:x+y
print(res(1,2))#3
例子二:
l=[(1,2),(6,3),(7,1)]
sorted(l,key=lambda x:x[1])
print(l)#[(1, 2), (6, 3), (7, 1)]
概念:
def test():#外层函数
a = 10
def test2():#内层函数、函数嵌套
print(a)#使用了外层函数地变量
return test2#将内层函数作为返回值
newFunc = test()
newFunc()
例子:分割线的生成
def line_config(content, length):
def line():
print("-"*(length // 2) + content + "-"*(length // 2))
return line
line1 = line_config("闭包", 40)
line1()#--------------------闭包--------------------
line2 = line_config("xxxx", 80)
line2()#----------------------------------------xxxx----------------------------------------
注意:
闭包中, 如果要修改引用的外层变量,需要使用 nonlocal 变量 声明;否则当做是闭包内, 新定义的变量
def test():#外层函数
a = 10
def test2():#内层函数
a=20
test2()
print(a)#输出:10,原因:不可变类型的引用传递
return test2
newFunc = test()
newFunc()
def test():#外层函数
a = 10
def test2():#内层函数
nonlocal a
a=20
test2()
print(a)#输出:20,原因:test2中修改的是全局的a
return test2
newFunc = test()
newFunc()