day8-散列类型与字符编码
初识散列类型(无序序列)
数据类型分为3种
前面已经学过了两种类型:
1.数值类型:int/bool/float 只能存储单个数据
2.序列类型:list/tuple/str,有序的存储多个数据--有序类型,有下标,可以进行切片索引步长的操作
3.散列类型:
1.可以存放多个数据
2.内部是无序的(没有下标)
3.内部数据不重复
集合跟字典都是散列类型
一、认识集合
集合(set)
表示形式为:用大括号{}包裹起来的数据,里面的数据用逗号隔开
集合的特性:
1.唯一性
2.无序性 主要是用来进行去重和逻辑判断
语法:
集合名={数据1,数据2,数据3,....}
案例:
room={'许叶彤','李震','尹天浩','帅过过','吊炸天'}
print(type(room))
print(room)
num={1,5,6,7,8,9,1,5,6,2}
print(num) #正常输出一个集合,里面的重复元素会自动去除,代表集合的唯一性
#print(num[2]) #报错,因为集合是无序类型 没有下标
集合可以进行简单的逻辑运算,交并差集
集合1 & 集合2-->获取交集--一个数据,两个集合里都有它
集合1 | 集合2-->获取并集--两个集合里的所有数据(去重)
集合1 - 集合2-->获取差集--两个集合之间,自己独有的数据
符号输入
& --> shift + 7
| --> shift + \
- --> 减号
生活例子:现在我们有两个碗
碗A{花菜,鸡肉,凤爪}
碗B{鸡肉,豆腐,梅菜}
交集-->两个碗里都有的菜-->鸡肉
并集-->两个碗里所有的菜-->花菜,鸡肉,凤爪,豆腐,梅菜
差集-->碗A-碗B-->碗A独有的数据-->花菜,凤爪
碗B-碗A-->碗A独有的数据-->豆腐,梅菜
num1={1,2,3}
num2={3,4,5}
print(num1&num2) #交集{3}
print(num1|num2) #并集{1, 2, 3, 4, 5}
print(num1-num2) #差集{1, 2}
print(num2-num1) #差集{4, 5}
集合里可以放很多数据(不能放列表)
集合里只能放不可变的数据
talk={'你好',66,9.9,True,(1,2,3),[1,2]}
print(talk) #集合里不能放列表,会报错
集合的本质:
1.存储非重复数据-->自动去重
2.进行逻辑判断,进行交并差运算
集合的方法
room= {‘麻子’,‘高启盛’,‘老莫’,‘高启强’}
增
add: 添加一个数据到集合里
集合.add(数据)
room.add('好好学习') #随机,因为无序所以随机增加
update: 把一个序列类型打散后添加到集合里
集合.update(序列数据)
room.update('别做坏事')
删
pop: 删除一个数据(随机删除)
集合.pop()
room.pop()
remove: 删除指定的数据
集合.remove(数据)
room.remove('高启强')
clear:清除所有数据
集合.clear()
room.clear() #set()
二、认识字典
字典(dict)
表示形式为:字典是用大括号包裹起来的数据,存储数据是以键值对的方式来存储,数据之间也要用逗号隔开,主要存储一些带有'说明'性质的数据
键值对 左边是键 中间冒号 右边是值
key:value-->相当于键是名字,值就是数据
键名一般是用字符串或整型来表示
值里面什么都可以放,放变量,函数,杂七杂八的都OK
声明语法:
字典名={键:值,键:值}
info={'姓名':'陌上','余额':8.8,'年龄':18}
info1={
'姓名':'陌上',
'余额':8.8,
'年龄':18
}
字典的输出:
print(字典名)
print(info)
print(type(info))
print(字典名[键名]) #输出指定键的值
print(info['姓名']) #陌上
#姓名=伊诺,年龄=18,余额=8.8
这里的字典的作用是一个说明效果,方便理解,有一个较好的可读性
用字典类型保存的数据有一点好处:
比起用列表/元组存储数据,他看起来更加清晰
info={'陌上',8.8,18} #这里的一些数据如果不加注释说明,可能不清楚表示什么东西
所以如果要的数据,有明显的对照关系,就可以用字典来保存,看起来更加的清晰明了
字典的特性:
1.字典是通过键值对的方式来获取数据,而不是通过下标索引获取
2.字典里的键是不可变的,只能使用数字,字符串,或者元组,不能使用列表
day=(2,3)
food={
1:'肉',
'水果':'葡萄',
day:'打折'
}
print(food)
info2={
[1,2]:'陌上'
} #报错
#print(info2) #报错,字典里的键是不可变的,只能使用数字,字符串,或者元组,不能使用列表
3.字典里的键值是可以修改的,还可以嵌套(字典里面还可以放字典)
info3={
'姓名':'陌上',
'余额':[8.8,9.9,10],
'地址':{1:'工作地址',2:'家乡地址'}
}
print(info3)
4.字典里键名是唯一的
info4={
'姓名':'伊诺',
'余额':8.8,
'年龄':18,
'年龄':19,
'年龄':20
} #只会保留最后一个年龄的键值对
print(info4)
总结:用一个看起来更清晰的方式来保存数据,保存方式为键值对
可以把键值对理解为变量 键就是变量名 值就是变量值
字典方法
info={
'姓名':'陌上',
'余额':8.8,
'年龄':18
}
增
setdefault: 给字典添加一个键值对. 如果已经有这个键了.就不会新增
[1.新增一个键,没有写值,值默认为空]
字典.setdefault(键名)
info.setdefault('身高') #没有值,值默认为空
[2.新增一个键值对]
字典.setdefault(键名,值)
info.setdefault('家乡','陕西宝鸡')
删
pop: 通过键名删除指定的数据
字典.pop(键名)
info.pop('年龄')
popitem: 删除一个键值对,从最后一个数据开始删
字典.popitem()
info.popitem()
clear: 清除整个字典
字典.clear()
info.clear()
改
update: 以键值对的方式修改数据.如果没有就新增
[1.修改数据]
字典.update({键:想修改的值})
info.update({'姓名':'陌上帅哥'})
[2.如果没有这个键值对,就转为新增]
字典.update({键:值})
info.update({'毕业学校':'西安邮电大学'})
[3.增加多个键值对]
字典.update({键:值,键:值})
info.update({'职业':'学生','性别':'女'})
字典[键名]=值 #修改指定键的值,键是存在的情况下会讲原来的值进行修改,否则添加为新的键值对
info['性别']='男' #找到info里面的性别 把值改为男
info['生肖']='猴' # 也算是一个新增方法,创建新的键值对
查
字典跟集合一样是无序序列,所以是无法通过下标进行获取数据,但是字典有查询数据的方法,但是查询的方法依旧也是用print来输出
get: 通过键名,获取值. 如果没有这个键,输出None
字典.get(键名)
print(info.get('余额'))
print(info.get('籍贯')) #没有籍贯这个键,就输出None
keys: 获取所有的键
字典.keys()
print(info.keys())
values: 获取所有的值
字典.values()
print(info.values())
items: 获取所有的键值对
字典.items()
print(info.items())
声明空变量
列表名=[] #声明一个空列表
元组名=() #声明一个空元组
字符串名='' #声明一个空字符串
集合名=set() #声明一个空集合
字典名={} #声明一个空字典
三、字符编码
如果你要出国玩,翻译工具-->把你想说的话,通过翻译工具的方式,传达给别人
计算机语言最底层是由0和1组成,计算机是怎么做到吧一堆的0和1变成我们看到的字,--->字符编码-->在计算机里面有一个翻译工具,作用就是把机器码数据转换成人类看的懂的字
字符编码--翻译工具--把计算机的东西翻译成人类能理解的东西
第一套字符编码叫ASCII码,里面收纳了一些常用符号,数字,字母-->没有中文或者其他语言
asciima表用法就有点类似于字典-->每个字在表里都有对应的一个序号,可以通过序号找到字,也可以通过字找到序号
但是随着科技进步发展,很多国家都有了自己的计算机技术能力,这时候这个ascii码表就不能满足需求了,-->我要用中文.日文
后面很多国家,地区都研发了一套自己的字符编码:
中国研发GBK编码-->有两万多个汉字
同时间中国台湾-->big5码,大五码,繁体字
每个国家的语言 不同 所以只显示自己国家的文字
用别的国家软件就容易出现问题
#就比如说用GBK写的内容用big5码打开就可能是乱码不通用
针对这个问题,有个国际组织,专门收集了全世界大部分的国家的语言文字,汇总做了一个大字典并推行使用,以后统一用大字典就可以尽量避免乱码问题-->utf-8
核心点:
1.目前世界上最主流的编码是utf-8,#大部分默认就用utf-8
2.一个程序是用什么编码写的,就用什么编码去打开
在程序中每个字都是有对应的序号
ord(字符) -->通过字符,找到序号
chr(序号) -->通过序号,找到字符
print(ord('A'))
print(ord('B'))
print(chr(65))
print('A'>'B') #实际比较的是ascii表的序号
凯撒密码 凯撒加密
计算机自动关机的指令 先按win+r 或者打开cmd
指令:shutdown -s -t 秒数
shutdown -a 取消关机
import os # 准备一个作案工具.这个工具可以让你运行cmd指令
code = "rgtscnvm,r,s2222" # 被加密过后的数据 #shutdown -s -t 秒数
run = "" # 空的字符串
for i in code: # 写了一个循环,把这个字符串里的所有元素都取了出来
run+= chr(ord(i)+1) # 把每个元素都+1,并添加到run里面
os.system(run)
day9-函数基础与函数参数
一、初识函数(function)
编程函数!=数学函数,里面的是逻辑,功能,而不是套公式
编程函数的作用是实现特定操作的一段代码
生活例子
我现在请客,每个人,我都点了一份一样的吃的
1.上校鸡块
2.可乐
3.薯条
100个同学 都点这样的 炸鸡店的老板我需要
这个点餐比较麻烦,我要重复说一百次
这个时候会用到-->套餐
出个套餐,美味套餐(上校鸡块,可乐,薯条)
我现在要点单 我只需要干嘛 美味套餐来一百份
程序:
把一些会经常用到代码保存起来,取个有意义的名字,以后要用直接调用就OK
变量:保存一个/多个数据
函数:保存的是一段或者多段代码
其实函数我们也并不陌生
print (输出函数) input(输入函数) 内置函数
函数的优点:
1.遇到重复代码时,可以定义为函数,省事
2.修改起来比较方便
本质:写好的一些代码,可以实现特定的功能,取个好记的名字保存起来方便使用
二、函数基础
函数的命名规则和变量是一样的:
1.由数字,字母,下划线组成
2.不能数字开头,不能有其他特殊符号
3.区分大小写 fun Fun
4.不能用关键字/内置函数 print input type
5.见名知意
函数如果没有特别作用,没想好别的名字 可以取名fun
函数的使用分为两步
#先定义再调用,程序是从上往下执行
1.声明-->define-->def
2.使用,调用函数
2.1定义函数&调用函数
1.定义函数
def 函数名():
代码内容
def fun():
print('好好学习')
调用函数:在函数名后面加个括号,就是调用函数
函数名()
fun()
实例:
#定义函数
def fun():
print('好好学习')
#调用函数
fun()
2.声明空函数,还没有想好内容,为了防止报错,就先写个pass
def 函数名():
pass
def fun_2():
pass
三、函数参数
函数里的数据如果是一成不变的,那很鸡肋,函数会接触到各种各样的数据,函数可以根据情况,来接收一些数据,并在函数里处理
让函数里的内容可以更加灵活,数据不是定死的-->函数参数
形参-->没有具体数据,只是先占个位置-->定义阶段
实参-->有具体的数据,在运行时取代形参-->调用阶段
声明带参函数:
def 函数名(形参):
代码
def fun(money):
print(f'我最喜欢{money}了')
调用带参函数
函数名(实参)
fun(50)
fun(100)
fun(1000000)
一个萝卜一个坑,不要多,也不要少,你定义了几个形参,就传几个实参,否则就会报错
3.1必备参数
有几个形参,就传几个实参,数量要一致
定义时:
def 函数名(形参1,形参2,..):
代码
调用时:
函数名(实参1,实参2,...)
例:
def add(num1,num2):
print(num1+num2)
add(70,520) #少写多写都会报错
3.2默认参数
在声明参数的时候就提前赋好值,作为一个默认的参数
定义时:
def 函数名(形参1,形参2=值):
代码
调用时:
函数名(实参1)
例:
def fun(money,people='陌上'):
print(f'{people}最喜欢{money}了')
fun(100)
fun(50)
fun(50,'许总') #不会报错,但是学_恒会覆盖原来的陌上
注意:赋值的默认参数要放右边,不能放左边
3.3不定长参数(1)
有的时候可能出现,不清楚这个函数会接收多少个参数,这时候就用不定长参数
不定长参数可以一次性接收多个数据, 接收到的数据为元组类型
不定长参数的表现形式:*
参数名是不固定,但是正常规范命名都是取名为*args
定义时:
def 函数名(*args):
代码
调用时:
函数名(值1,值2,值3)
例:
def room(*args):
print(args)
print(args[1])
room('李白','王维','杜甫','杜牧','老子','孔子')
#想好了具体传什么形参的时候,剩下的还没有想好,也可以结合不定长参数1使用
def message(name,age,*args):
print('''
-----个人信息表-----
姓名{}
年龄{}
'''.format(name,age))
print(args) #('李白', 25, 8.8, (0, 1))
print(args[0]) #李白
print(args[1:]) #(25, 8.8, (0, 1))
print(args[1::2]) #(25, (0, 1))
message('陌上',18,'李白',25,8.8,(0,1))
3.4不定长参数(2)
可以一次性接收多个数据,接收的数据类型为键值对,得到的数据为字典类型
不定长参数2的表示形式为:**
参数名同样不固定,但最好叫**kwargs
定义时:
def 函数名(**kwargs):
代码
调用时:
函数名(键=值,键=值) #键不用加引号
实例:
def fun_2(**kwargs):
print(kwargs)
fun_2(name='陌上',age=18)
def grade(C,M,**kwargs):
print(f'Chinese{C},Math{M}')
print(kwargs)
grade(98,99,java=100,python=500)
def fun_3(a,b,*args,**kwargs):
print(a*b)
print(args)
print(kwargs)
fun_3(5,10,java=100) #a对应了5,b对应了10,java=100对应了**kwargs,*args没有传值,所以是一个空元组
fun_3(5,10,5,6,7,8,9,java=100)
注意:不定长参数1必须要在不定长参数2前面
四、返回值(return)
def add(num1,num2):
print(num1+num2)
add(520,70)
a=add(520,70)
# b=a+1 #报错 不支持无类型跟整型相加
# print(b)
print(a)
如果没有定义返回值 会返回一个None空
在函数里,一个数据只是用print输出.那就只能看,不能用,如果你想要用这个数据,需要的是return来返回,而不是print输出
return 返回值
把值返回给函数本身,可以用来使用 返回值一般是结合函数参数来使用
那现在我们要用一个有返回值的函数怎么做?
1.定义一个带有return返回值的函数
def 函数名():
return 数据
2.输出返回值内容:把函数名()用print包裹起来,这个动作就会达到目的是:
1.运行函数,2.输出函数的返回值
print(函数名())
实例:
def fun(a,b):
return a+b
fun(3,5) #直接调用函数 不会显示出返回值的内容
print(fun(3, 5)) #所以要打印返回值需要print
返回值可以有多个,并且也可以输出多个返回值,得到的类型是元组类型
def 函数名():
return 返回值1,返回值2,...
def fun3():
return '么么哒',1,True,[1,2,3]
print(fun3())
得到的返回值还有一种用法是可以把函数返回值赋值给变量
变量名=函数名() #把函数返回值赋值给变量
例:
def fun(a,b):
return a+b
fun(3,5) #直接调用函数 不会显示出返回值的内容
print(fun(3, 5))
a=fun(3,5)
c=a+10
print(c)
注意:
在return后面的代码是不会执行的,因为函数执行到return就会结束
def talk():
print('大家留下加班')
print('没有加班费')
return 'ok'
print('加你个大头鬼')
talk() #直接调用函数不会显示出返回值的内容
print(talk()) #输出返回值内容
print(talk) #内存地址
返回值细节:
1.返回值的类型是不限的,int/str/folat/list/dict都可以,也可以返回一个函数
2.返回值的数量数不限的,可以返回多个数据,得到的数据是元组类型
五、内置函数(基础篇)
python自带的一些功能函数
序列类型/散列类型方法
数据类型转换 int() str() list()
特点:
1.都有一个小括号
2.每个函数都有自己的功能
print():输出函数
input():输入函数
type() : 获取数据类型函数
len(): 获取数据长度函数(里面有多少个元素)
min(): 获取最小值函数
max(): 获取最大值函数
sum(): 获取数据的和 函数
li = [1, 2, 3, 4, 5, 6, 8, 9]
print(max(li)) #最大值
print(min(li)) #最小值
print(sum(li))#和
print(len(li)) #长度
函数命名不要取名为内置函数的名字!!!
六、文档字符串
基于函数的注释,看起来和注释差不多,但是可以被调用,在学函数是,更推荐使用文档字符串,里面可以写
1.这个函数是干嘛用的
2.这个函数参数是干嘛用的
3.返回值是干嘛用的
def add(a,b):
'''
我是一个加法函数
:param a:int型
:param b:float型
:return:a+b
'''
return a+b
print(add(2,2.3))
print(add.__doc__)
print(print.__doc__)
输出方式:注意是两个下划线
函数名.__doc__
print(print.__doc__)
print(input.__doc__)
print(max.__doc__)
day10复习拓展
第6-9节课复习
流程控制语句
三大执行方式:
1.顺序执行:程序从上往下依次执行
2.选择执行:根据条件满足与否,执行对应的代码
3.循环执行:根据条件满足与否,循环执行对应的代码
if 选择执行/分支语句
分支语句分为三种
1.单分支--if--如果满足if条件就执行对应代码
if 判断条件:
执行语句
2.双分支--if,else--如果满足if条件就执行if里的代码,否则执行else里的代码
if 判断条件:
执行语句
else:
执行语句
3.多分支--if,elif,else--如果满足if条件就执行if里的代码,不满足就接着判断是够满足elif的代码,满足就执行elif的代码,elif也不满足才执行else的代码
if 判断条件:
执行语句
elif 判断条件:
执行语句
else:
执行语句
一组分支里面,if和else只能有一个,elif可以有多个
if还有个特性 判断条件有值就执行 没值的情况就不执行
有值为真 没有值为假(0,None,'',[],{},set())
流程控制语句中代码块的概念,通过tab缩进来控制,一般一个tab是4个空格
循环语句:
判断条件是否满足,如果满足条件就循环执行,不满足是结束循环
死循环--一直执行,不会结束的循环
while 循环:
语法:
while 循环条件:
执行语句
更新语句 #如果你条件不更新,那就会一直死循环
num=1
while num<=100:
print(666)
num+=1
for 循环:在(1)循环已知次数 (2)遍历数据 都比while更高效
语法:
for 变量 in 可迭代对象: #可迭代对象理解为有多个数据的值即可,这里的变量取名为i
执行语句
talk='伊诺老师提前祝大家端午安康'
for i in talk:
print(i)
for i in range(10) #循环10次,i的值为0-9
for i in range(1,11) #循环10次,i的值为1-10
for i in range(1,11,2) #循环5次,i的值为1,3,5,7,9 步长为2
range的起点默认为0.终点到他的前一位
break--直接结束本轮循环
continue--跳过本次训话
break 和continue 一般结合循环里的if来使用 如果满足条件就break
pass --没有写好内容 为了防止报错 可以先写个这个
序列类型方法:
方法有很多,不需要死记硬背,要用的时候根据需求来查
1.列表的方法中,增删改直接写,不需要print,查需要print
2.元组只有查询方法,因为元组不支持修改,所以元组的内容要结合print来输出
3.字符串的数据是不可变的,所以字符串也要结合print来输出
用的比较多的方法:
append--列表追加数据
insert--列表插入数据
index--查询数据下标
replace--字符串修改数据
散列类型(set集合,dict字典):
1.可以存储多个数据
2.里面的数据没有顺序概念(没有下标)
3.数据不能重复
set-->集合,表示形式为用大括号包裹起来的数据,里面的数据用逗号隔开,集合里不会存储重复数据
set1 = {1,1,2,3,5,0,4,7,98,7,7,52,0} #重复数据不会真的存进去
集合可以用来进行简单的逻辑运算
&交集(两个集合里共用的元素)
|并集(两个集合所有元素)
-差集(两个集合间,独有的元素)
集合主要用来:
1.数据去重
2.进行简单的交并差判断
dict-->字典,示形式为用大括号包裹起来的数据,里面的数据以键值对的方式来存储,里面的数据用逗号隔开
键值对语法: 键:值 变量名:变量值
info={
'姓名':'陌上',
'年龄':18,
'美女':True
}
用键值对保存的数据,看起来更加清晰明了,所以如果要 保存的数据有明显对应关系,就可以用字典来存储数据
键是唯一的,值可以是任意类型(数值,序列,散列,函数)
字典的输出方式通过键名输出
字典名[键名]
print(info['姓名'])
字典名[键名]=值 #修改这个键的值
info['美女']='丑女'
函数(function):
函数的概念就是把一些经常用到的 代码保存起来,取个名字,以后要用功能,直接调用即可
类似于生活中套餐
函数的使用分为两步:1定义(define) 2.调用
定义函数:
<1>定义一个普通函数
def 函数名():
代码
def fun():
print('好好学习')
<2>定义一个空函数
def 函数名():
pass
def fun2():
pass
<3>定义一个带有返回值的函数
def 函数名():
return 返回值
def fun3():
return 123
<4>定义一个带参函数
def 函数名(参数):
代码
def fun4(name):
print(f'{name}好好学习')
调用函数:
1.直接调用函数
函数名()
fun() #执行fun里的代码
2.输出返回值/函数内存地址
print(函数名) #输出函数内存地址
print(fun3)
print(函数名())
print(fun3())
3.调用带参函数:
fun4('陌上')
函数参数:
形参:没有具体的值,只是先占个位置--定义时
实参:有具体的值,在调用时取代形参运行--调用时
<1>必备参数-- 形参,实参数量要一致,一个萝卜一个坑
def fun(a,b):
print(a,b)
fun(1,2,)
<2>默认参数-- 在定义形参时,就给里面的某个变量赋值,就可以不用传参,赋值只能给右边的数据赋值
def fun_2(age,name='陌上'):
print(age,name)
fun_2(18)
fun_2(18,'帅哥') #帅哥覆盖原来的默认参数值陌上
<3>不定长参数1-- 在不清楚要接收几个数据的情况下可以用它,一次性接收多个数据数据,接收的数据类型是元组类型数据,表现形式为 *参数名 一般取名为*args
def fun_3(*args):
print(args)
print(type(args))
fun_3(66,888,True,'陌上')
<4>不定长参数2-- 在不清楚要接收几个数据的情况下可以用它, 一次性接收多个数据数据 ,可以接收键值对数据,接收的数据类型是字典类型数据,表现形式为 **参数名,一般取名为 **kwargs
def fun_4(**kwargs):
print(kwargs)
print(type(kwargs))
fun_4(python=90,math=80,age=18,name='陌上') #键不用打引号
return返回值:
一个数据如果使用print,那就是只是作为输出,是只能看,不能用
所以一个数据想被继续使用,就是通过return的方式,把他返回出去
返回值的默认值为None 为空
return后面的代码是不会再运行
返回值的数量/类型是不限的
文档字符串:
写在函数里的注释,可以被调用,里面写的是函数的相关说明.参数/返回值/这个函数的说明
def 函数名():
"""文档字符串的内容"""
可以通过函数名.__doc__的方式输出 文档字符串的内容
print(print.__doc__)
函数注意—高内聚低耦合
为什么要分开写 我把加减乘除写到一个函数里不可以吗???--避免一个错,全部错
我把加减乘除函数都写在了一个函数里面,然后里面的除法功能出错了,我这个函数还能用吗?--不能使用
把加减乘除函数分开写在4个函数里,然后里面的除法功能出错了,我这个函数还能用吗?可以先把他屏蔽 注释 也不会影响其他功能
专注做好一件事 彼此联系不要过于紧密
高内聚-->一个程序里/函数里做的事情尽量统一/专一,一个函数做好一个功能就可以了,而不是一个函数里写一堆的功能 容易一个错 整个错
低耦合-->程序与程序之间,函数与函数之间的关联不要过于紧密 各做隔得 ,避免一个错 全部错