Python 学习笔记 Day4


集合

Python语言的集合类型与数学中的集合一致:包含0个或多个数据项的无序组合,用大括号 { }表示,它可以动态增加或删除,但不能比较和排序

>>>S1 = {1,'ada',(4,5,3),'1',1.0}
>>>S2 = set('人生若只如初见') # set()表示空集
>>>S3 = set((1,5,6,1))
>>>print(S2)
{'只', '若', '如', '见', '生', '人', '初'}
>>>print(S3)
{1, 5, 6}

⭐注:set([iterable])函数的参数只能创建可迭代对象:列表、元组、字典、字符串

集合的性质

确定性

给定一个集合,任给一个元素,该元素或者属于或者不属于该集合,二者必居其一,不允许有模棱两可的情况出现

互异性

一个集合中,任何两个元素都认为是不相同的,由于每个元素只能出现一次,所以使用集合类型能够过滤掉集合本身的重复的元素

无序性

一个集合中,每个元素的地位都是相同的,元素之间是无序的,即集合是无序组合,因此它没有索引和位置的概念,集合的输出顺序和定义顺序可以不一致
⭐注:集合里面不能存可变数据类型(字典、集合、列表)

>>>S = {1,'ada',(4,5,3),'1',1.0}
>>>print(len(S))
4

>>>print(type(S))
<class 'set'>

>>>print(S)
{1, '1', 'ada', (4, 5, 3)}

集合的运算

在这里插入图片描述

>>>A = {1,'ada',(4,5,3),'1',1.0}
>>>B = {1,(1,3.14,'5A')}
>>>print(A-B)
{'1', 'ada', (4, 5, 3)}

>>>print(A|B)
{1, (1, 3.14, '5A'), (4, 5, 3), '1', 'ada'}

>>>print(A&B)
{1}

>>>print(A^B)
{'1', (1, 3.14, '5A'), 'ada', (4, 5, 3)}

集合常用函数

函数或方法描述
s.issubset(t)s 中所有的元素是否都是 t 的成员,s <= t
s.issuperset(t)t 中所有的元素是否都是 s 的成员 ,s >= t
s.add(obj)将 obj 添加到 s
s.pop()移除并返回 s 中的随机一个元素
s.discard(obj)将 obj 从 s 中删除,如果 s 中不存在 obj,也不会报错
s.remove(obj)将 obj 从 s 中删除,如果 s 中不存在 obj,会报错
s.clear()清除 s 中的所有元素
s.copy()返回 s 的浅拷贝
x in sx是s的元素返回True,否则返回False
x not in sx不是s的元素返回True,否则返回False

字典

字典是键值对的集合
字典是可变无序的,无序指的是因为字典本质是hash表(hash表的数据结构注定它就是无序的),但是字典的元素本质上是存储在一个连续列表中的,所以在存储方面是有序的

字典的创建

Python语言中的字典使用通过大括号{ }或dict()建立,每个元素是一组键值对,使用方式如下:

'''
字典的创建方式主要分为以下三种:
Ⅰ.{<键1>:<值1>, <键2>:<值2>,<键3>:<值3>,...,<键n>:<值n>}
Ⅱ.Zip()函数
   dict(iterable, **kwarg)  *arg会把多出来的位置参数转化为tuple
                            **kwarg会把关键字参数转化为dict
Ⅲ.fromkeys
   dict.fromkeys(seq[, value]) 
   seq -- 字典键值列表。
   value -- 可选参数, 设置键序列(seq)的值。                   
'''
>>> dict(a='a', b='b', c='c')     
{'a': 'a', 'b': 'b', 'c': 'c'}

>>> dict(zip(['1, '2', '3'], [1, 2, 3]))   # 映射函数方式来构造字典
{'1': 1, '2': 2, '3': 3}

>>> dict([('1', 1), ('2', 2), ('3', 3)])   # 可迭代对象方式来构造字典
{'1': 1, '2': 2, '3': 3}

>>> dict.fromkeys(['name','age','job'])    #值可以先不设
{'name': None, 'age': None, 'job': None}

⭐注:
1.虽然集合和字典都是用大括号表示,但是如果直接使用大括号{ },则会生成字典类型而不是集合
2.字典的各个元素没有顺序之分
3.字典的“键”是任意的不可变数据,如:整数、浮点数、字符串、元组,而可变类型数据不能作为键,如:字典、集合、列表
4.字典的“键”不能重复,否则会被覆盖(后出现的覆盖前面的出现的)

>>>a={1:'1',1:'2',1:'555'}
>>>print(a)
{1: '555'}

5.字典的“值”可以是任何类型的数据,并且可以重复
6.在Python中,字典是唯一的映射类型,键 → 值
7.字典和列表

对比列表字典
使用方式[3, 14]{‘a’: 2, ‘s’: 71}
访问元素的方式索引
有序性有序无序
可变性可变可变
表征的数据结构数组、堆栈、队列等哈希表等

字典的访问

函数描述
len(d)获得字典d的元素个数(长度)
min(d)字典d中键的最小值
max(d)字典d中键的最大值
dict(d)生成一个空字典
d.keys()返回所有的键信息
d.values()返回所有值的信息
d.items()返回所有键值对
d.get(key,default)键存在返回相应的值,否则返回默认值(默认值可以设置)
d.setdefault(key,default)取出一个不存在的键的值(返回默认键的值,并且将新的键值保存在字典中)
obj in d检测obj是否在字典d中

⭐注:get()和setdefault()的区别在于,当取出一个不存在的键的值的时候,get会返回该值,但不会保存在原字典中,而setdefault会把新查询的键值对保留在原字典中

>>>a = {'name':'Leo','age':8}
>>>print(a['name'])
Leo

>>>print(a['job'])       #字典没有该键,报错了
Traceback (most recent call last):
  File "C:/Users/Leonardo/PycharmProjects/untitled/1.py", line 4, in <module>
    print(a['job'])
KeyError: 'job'

>>>print(a.get('问号'))
None                        #键不存在返回None

>>>print(a.get('问号','?')) #设定默认返回的对象
?

>>>print(a.items())
dict_items([('name', 'Leo'), ('age', 8)])

>>>print(a.keys())
dict_keys(['name', 'age'])

>>>print(a.values())
dict_values(['Leo', 8])

>>>print(len(a))
2

>>>print(123 in a)
False

字典的添加修改和删除

函数说明
dict1.update(dict2)把字典参数 dict2 的key/value(键/值)对更新到字典 dict1 里,如果key重复直接覆盖
dict.pop(key[,default])删除字典给定键 key 所对应的值,返回值为被删除的值
dict.popitem()随机地从字典中取出一个键值对,以元组(key,value)形式返回,同时将该键值对从字典中删除
del d[obj]删除字典中某一个元素obj
d.clear()清空字典

1.给字典新增“键值对",若“键”已经定义了,则覆盖旧的键值对,如果还没有定义,那么就新增新的“键值对”

>>>a = {'name':'Leo','age':8}
>>>a['name']='Leonardo'
>>>a['sex']='male'
>>>print(a)
{'name': 'Leonardo', 'age': 8, 'sex': 'male'}

2.update()

>>>a = {'name':'Leo','age':8}
>>>b = {'sex':'male','money':5641230}
>>>a.update(b)
>>>print(a)
{'name': 'Leo', 'age': 8, 'sex': 'male', 'money': 5641230}

3.del

>>>a = {'name':'Leo','age':8}
>>>del a['age']
>>>print(a)
{'name': 'Leo'}

4.pop

>>>a = {'name':'Leo','age':8}
>>>b=a.pop('name')
>>>print(b)
Leo

字典的遍历

dict = {'date':'2020.5.22','name':'Leo','work':"遍历",'number':314}
for i in dict:   #遍历字典中的键
    print(i)
print('-----------------------------------')
for value in dict.values():  # 遍历字典中的值
        print(value)
print('-----------------------------------')
for item in dict.items():  #遍历字典中的元素
    print(item)
print('-----------------------------------')
for i in dict:
    print("本次循环得到的key为{},对应的值为{}".format(i,dict[i]))

date
name
work
number
-----------------------------------
2020.5.22
Leo
遍历
314
-----------------------------------
('date', '2020.5.22')
('name', 'Leo')
('work', '遍历')
('number', 314)
-----------------------------------
本次循环得到的key为date,对应的值为2020.5.22
本次循环得到的key为name,对应的值为Leo
本次循环得到的key为work,对应的值为遍历
本次循环得到的key为number,对应的值为314

练习
在这里插入图片描述

r1 = {'name':'高小一','age':18,'salary':88888,'city':'BeiJing'}
r2=  {'name':'高小二','age':19,'salary':66666,'city':'ShangHai'}
r3 = {'name':'高小三','age':20,'salary':99999,'city':'ShenZhen'}
print('第1题')
tb=[r1,r2,r3]
#获得第二个人的薪资
print(tb[1].get('salary'))

print('第2题')
#遍历所有人的工资
for i in range(len(tb)):
    print('{}的工资是{}'.format(tb[i].get('name'),tb[i].get('salary')))
print('第3题')
#打印该表
for i in range(len(tb)):
    print(tb[i].items())

for i in range(len(tb)):
    print(tb[i].get('name'),tb[i].get('age'),tb[i].get('salary'),tb[i].get('city'))1666662题
高小一的工资是88888
高小二的工资是66666
高小三的工资是999993题
dict_items([('name', '高小一'), ('age', 18), ('salary', 88888), ('city', 'BeiJing')])
dict_items([('name', '高小二'), ('age', 19), ('salary', 66666), ('city', 'ShangHai')])
dict_items([('name', '高小三'), ('age', 20), ('salary', 99999), ('city', 'ShenZhen')])
高小一 18 88888 BeiJing
高小二 19 66666 ShangHai
高小三 20 99999 ShenZhen

序列解包

序列解包可以方便地对多个变量赋值,它可以用到元组、列表、字典中

x,y,z=1,2,3
(a,b,c)=(4,5,6)
[a,b,c] = [7,8,9]

s = {'name':'Leo','age':8,'sex':'male'}
name,age,sex=s #默认对键进行操作
print(name) #输出 name
print(age) #输出 age
print(sex) #输出 sex
name,age,sex=s.values() #对值进行操作
print(name) #输出 Leo
print(age) #输出 8
print(sex) #输出 male
name,age,sex=s.items()  #对 键值对 进行操作
print(name) #输出 ('name', 'Leo')
print(age) #输出 ('age', 8)
print(sex) #输出 ('sex', 'male')

字典的核心底层原理

字典对象的核心是散列表,散列表是一个稀疏数组(总是有空白元素的数组),数组的每个单元叫bucket,每个bucket有两个部分:一个是键对象的引用,一个是值对象的引用,所有的bucket结构和大小一致,我们可以通过偏移量来读取指定的bucket
在这里插入图片描述
怎样通过key对应索引(数字)?
1.将键值放进字典的底层过程(存)
①先建立一个空的字典,假设字典a创建完之后散列表(稀疏数组)的长度是8

>>>a = {}

在这里插入图片描述
②现在,我们要把 ‘name’=Leo 这个键值对放入字典对象a中,要完成这个过程,首先要先计算’name’的散列值,在Python可以用hash()来计算


>>>a = {}
>>>a['name']='Leo'
>>>print(bin(hash('name')))
0b111000110010110000011101111000011111101101011000110100100010111

③由于稀疏数组的长度是8,我们可以拿计算出的散列值最右边3位数字作为偏移量,即“111”,对应二进制数字是7,我们查看对应的bucket是否为空,如果是空的,就可以把键值对放进去
在这里插入图片描述
如果不为空,则再向右取3位作为偏移量,即“010",对应二进制数字是2,再看偏移量为4的bucket是否是空的,直到找到为空的bucket能将键值对放进去为止,流程如如下:
在这里插入图片描述
⭐注:如果该数组接近2/3已经被占用了,数组会自动扩大
2.根据键查找键值对的底层过程(取)
在这里插入图片描述
用法总结:
1.键必须可散列:
(1)数字、字符串、元组都是可散列的
(2)自定义对象需要支持下面三点:
①支持hash()函数
②支持通过__eq()__方法检测相等性
③若a==b为真,则hash(a)==hash(b)也为真
2.字典在内存中开销巨大,典型的空间换时间
3.键查询速度很快
4.往字典里面添加新的键可能会导致扩容,从而引起散列表中键的次序变化,所以不要在遍历字典的同时对字典进行修改

程序的控制结构

![在这里插入图片描述](https://img-blog.csdnimg.cn/20200522083901637.png?

条件表达式详解

在选择和循环结构中,条件真假的情况如下

真的假的
TrueFalse
非零整数or非零浮点数0 or 0.0
非空字符串空字符串
非空字典空字典
非空列表空列表
非空元组空元组
非空range空range
非空迭代对象空迭代对象
None

迭代:如果给定一个list或tuple,我们可以通过for循环来遍历这个list或tuple,这种遍历我们称为迭代(Iteration)
Python的for循环不仅可以用在list或tuple上,还可以作用在其他可迭代对象上
可以直接作用于for循环的对象统称为可迭代对象(Iterable),如列表、元组、字典、集合、字符串等

如何判断一个对象是可迭代对象呢?
我们可以通过collections模块的Iterable类型判断

>>> from collections.abc import Iterable

>>> isinstance('abc', Iterable) # str是否可迭代
True

>>> isinstance([1,2,3], Iterable) # list是否可迭代
True

>>> isinstance(123, Iterable) # 整数是否可迭代
False 

测试各种表达式:

if 3: #整数作为条件表达式
    print('ok')

a=[] #列表作为条件表达式,是空列表,是False
if a:
    print('空列表,False')

s='False' #非空字符串是True
if s:
    print('非空字符串,True')

c=9
if 3<c<20:
    print('c在3和20之间')
if 3<c and c<20:
    print('c大于3且c小于20')

if True: #布尔值
    print('True')


ok
非空字符串,True
c在320之间
c大于3且c小于20
True

注:在Python,条件表达式中不能有赋值操作符 “ = ”

分支结构

分支结构通过判断条件是否成立,来决定执行哪个分支
分支结构主要分三种:单分支、双分支和多分支

单分支if

if语句单分支结构的语法形式如下:

if 条件:
    语句/语句块

⭐注:
1.条件表达式:可以是逻辑表达式、关系表达式、算数表达式等
2.语句/语句块:可以是一句或者多句,但缩进必须对齐一致
在这里插入图片描述

for i in range(1000000000000000):
    num = eval(input('猜猜我多大? \n'))
    if num == 18:
        print('没错我18')
        break

双分支if-else

双分支结构语法格式如下:

if 条件:
    语句1/语句块1
else:
    语句2/语句块2
#例
num = eval(input('输入一个数字:\n'))
if num<10:
    print(num)
else:
    print('数字太大')

输入一个数字:
60
数字太大

在这里插入图片描述

三元条件运算符

Python提供了三元运算符,用来在某些简单的双分支赋值情况
三元运算符语法结构如下:

条件为真的值 if (条件表达式) else 条件为假的值
num = eval(input('输入一个数字:\n'))
print(num if (num)<10 else"数字太大")

输入一个数字:
60
数字太大

多分支if-elif-else

多分支结构语法结构如下:

if 条件1:
    语句1/语块1
elif 条件2:
    语句2/语块2
... ...
elif 条件n:
    语句n/语块n
else:              #可以不写
    语句n+1/语块n+1
#多分支结构中,几个分支之间是有逻辑关系的,不能随意颠倒顺序
'''
练习: 输入一个学生的成绩,将其转化成简单描述:
不及格 小于60
及格 60-79
良好 80-89
优秀 90-100
'''

while 666:
    score = eval(input('请输入您的成绩:\n'))
    if 0<=score<=100:
        if score < 60:
            grade = '不及格哦,请继续加油!'
            break
        elif 60 <= score < 79:
            grade = '及格,潜力很大'
            break
        elif 80 <= score < 89:
            grade = '良好,差点就优秀了'
            break
        elif 90 <= score <= 100:
            grade = '优秀,请继续保持'
            break
    else:
            print('请输入正确的数字!')
print('您分数是{},等级是 {}'.format(score,grade))

#输入点的坐标,判断该点在第几象限
x = float(input("请输入横坐标:"))
y = float(input("请输入纵坐标:"))
if x > 0 and y > 0:
     print("该点在第一象限")
elif x < 0 and y > 0:
     print("该点在第二象限")
elif x < 0 and y < 0:
     print("该点在第三象限")
elif x > 0 and y < 0:
     print("该点在第四象限")
elif x== 0 and y!=0:
     print("该点在x轴")
elif y== 0 and x!=0:
     print("该点在y轴")
else:
     print("该点在原点")

在这里插入图片描述

分支结构的嵌套

在使用嵌套的时候,一定要控制好不同级别代码块的缩进,因为缩进决定了从属关系
嵌套语法结构如下:

if 表达式1:
    语句1
    if 表达式2:
        语句2
    else:
        语句3
else:
    if 表达式4:
        语句4
'''
输入一个分数0-100之间
A 90以上
B 80以上
C 70以上
D 60以上
E 60以下
'''
score =eval(input('请输入一个0-100的数字:\n'))
grade =''
if score>100 or score<0:
    score = eval(input('输入错误,请重新输入:\n'))
else:
    if score>=90:
        grade='A'
    elif score>=80:
        grade='B'
    elif score>=70:
        grade='C'
    elif score>=60:
        grade='D'
    else:
        grade='E'
print('分数为{},等级为{}'.format(score,grade))

或者
score =eval(input('请输入一个0-100的数字:\n'))
degree='ABCDE'
num=0
if score >100 or score<0:
    print('输入错误,请重新输入!')
else:
    num=score//10
    if num<6:
        num=5
    print(degree[9-num])

循环结构

循环结构用来重复执行一条或者多条语句,流程图如下:
在这里插入图片描述
在这里插入图片描述

while循环

while循环的语法结构如下:

while 条件:
    循环体语句
#打印0~10
num=0
while num<=10:
    print(num)
    num+=1
    
0
1
2
3
4
5
6
7
8
9
10

#打印1-100的和
num=0
sum=0
while num<=100:
    sum = sum+num
    num+=1
print(sum)

5050
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值