PythonNO.3
一、字典
字典:Python内置的数据结构之一,与列表一样是一个可变序列(可以执行增删改,对象地址不发生更改)以键值对的方式存储数据,字典是一个无序的序列
举例:scores={ ‘张三’:100,‘李四’:98,‘王五’:56},其中【‘张三’:100】=【键 :值】
1.字典的实现原理
字典的实现原理与查字典类似,查字典是现根据部首或拼音查找对应的页码,
Python中的字典是根据Key查找values所在的位置,用 hash(key)查找
2.字典的创建
1.最常用的方式:使用花括号:举例:scores={ ‘张三’:100,‘李四’:98,‘王五’:56}
2.使用内置函数dict():举例:student=dict(name=‘jack’,age=20),等号左边是键,右边是值
空字典:{}
scores={ '张三':100,'李四':98,'王五':56}
print(scores,type(scores)) # scores.type:<class 'dict'>
student=dict(小米=15,小欢=16)
print(student,type(student))
empty={}
print(empty,type(empty))
3.字典中元素的value的获取
1.[]:举例:scores[‘张三’]。[]取值如果字典中不存在指定的key,抛出keyError异常
2.get()方法:举例:scores.get(‘张三’)。get()方法取值,如果字典中不存在指定的key,并不会抛出keyError异常而是返回None,可以通过参数设置默认的value,以便指定的key不存在时返回
print(scores['张三'])
print(scores.get('李四'))
print(scores.get('jack',100)) #指定的'jack'不存在时返回100
4.key的判断,字典元素的删除,字典元素的新增
key的判断:in ,not in
字典元素的删除:del scores[‘张三’] 删除指定的key-value对
字典元素的新增:scores[‘李白’]=96
print('张三' in scores)
print('张三' not in scores)
del scores['张三'] #删除
print(scores.get('张三'))
scores['李白']=96 #新增
print(scores['李白'])
scores['张三'] =68 #修改
print(scores['张三'])
5.获取字典视图:
1.keys():获取字典中的所有key
2.values():获取字典中的所有value
3.items():获取字典中所有的key,value对
scores={ '张三':100,'李四':98,'王五':56}
key=scores.keys()
print(key,type(key))#dict_keys(['张三', '李四', '王五']) <class 'dict_keys'>
value=scores.values()
print(value,type(value))#dict_values([100, 98, 56]) <class 'dict_values'>
item=scores.items()
print(item,type(item))#dict_items([('张三', 100), ('李四', 98), ('王五', 56)]) <class 'dict_items'>
print(list(item))#[('张三', 100), ('李四', 98), ('王五', 56)]
#转换之后的列表是由元组组成的
6.字典元素的遍历:
for item in scores:
print(item)
#item代表字典元素中的键
for item in scores:
print(item,scores[item])
7.字典的特点:
1.字典中的所有元素都是一个key-value对,key不允许重复,value可以重复
2.字典中的元素是无序的
3.字典中的key必须是不可变对象
4.字典也可以根据需要动态的伸缩
5.字典会浪费较大的内存,是一种使用空间换时间的数据结构
name={'name':'张三','name':'李四'}
print(name)#{'name': '李四'} 出现相同的键,会出现值覆盖现象
name={'name':'张三','nikname':'张三'}
print(name)#{'name': '张三', 'nikname': '张三'}
8.字典生成式:
内置函数zip():用于将可迭代的对象作为参数,将对象中对应的元素打包成一个元组,然后返回由这些元组组成的列表
.upper():改为大写
items=['fruits','books','others']
price=[96,78,85]
d={items.upper():price for items,price in zip(items,price)}
print(d)
#若键值两者数目不一,选择少的
二、元组
元组:Python内置的数据结构之一,与字符串一样是一个不可变序列(没有增,删,改的操作)
1.元组的创建方式:
1.直接小括号:t=(‘Python’,‘hello’,90),小括号可以省略
2.使用内置函数tuple():t=tuple((‘Python’,‘hello’,90))
3.只包含一个元组元素需要使用逗号和小括号:t=(10,)
4.空元组:(),tuple()
t='Python','hello',90
t1=('Python','hello',90)
print(t,type(t)) #<class 'tuple'>
print(t1,type(t1)) #<class 'tuple'>
t2=tuple(('Python','hello',90))
print(t2,type(t2)) #<class 'tuple'>
t3=(10,)
print(t3,type(t3)) #<class 'tuple'>
t4=()
print(t4,type(t4))#<class 'tuple'>
a=(10,[20,30],40)
print(a,type(a))
print(a[0],a[1],a[2],id(a[1]))
a[1].append(60) # 往元组中的列表里添加元素
print(a[1],id(a[1])) # 列表地址不变
2.元组的遍历:
- 使用索引,t[0],t[1]
2.遍历元组:for in
t=(‘Python’,‘hello’,90)
for item in t:
print(item)
t = ('Python', 'hello', 90)
for item in t:
print(item)
三、集合
集合:Python语言提供的内置数据结构,与列表、字典一样都属于可变类型的序列,集合是没有value的字典
1. 集合的创建:
1.直接{}
2.使用内置函数set()
2.定义空集合:set()
s={'Python','155',1212,1,1} #与字典一样,会把重复的元素删掉
print(s,type(s))
s1=set(range(6))
print(s1,type(s1))
print(set([1,2,26,42]))
print(set({1,52,26,52}))
print(set((1,52,26,72)))
print(set('12')) #{'1', '2'}
print(set()) #set()
#集合中的元素是无序的,输出结果不一
2. 集合元素的判断,新增,删除
集合元素的判断:in,not in
集合元素的新增:
1.调用add()方法:一次添加一个元素
2.调用update()方法:至少添加一个元素
集合元素的删除:
1.调用remove()方法:一次删除一个指定元素,如果指定元素不存在抛出KeyError异常
2.调用discard()方法:一次删除一个指定元素,如果指定元素不存在不抛出异常
3.调用pop()方法:一次只删除一个任意元素
4.调用clear()方法:清空集合
a={10,20,30}
print(a)
a.add(50)
print(a)
a.update((1,3,4))
print(a)
a.update({5,21,30,65,5})
print(a)
a.remove(10)
print(a)
a.pop()#无参
print(a)
a.clear()
print(a)
3. 集合间的关系:
1.两集合是否相等 :用运算符== 或!=判断
2.一个集合是否是另一个集合的子集:调用issubset进行判断
3.一个集合是否是另一个集合的超集:调用issuperset进行判断
4.两集合是否没有交集:调用isdisjoint进行判断
a1={10,20,30}
a2={10,30,20}
print(a1==a2) #True
print(a1 is a2) #False,比较地址值
a3={10,20,40}
a4={10,20}
print(a3.issubset(a4))
print(a4.issubset(a3)) #s4是s3的子集
print(a3.issuperset(a4)) #s3是s4的超集
print(a4.isdisjoint(a3)) #False,表示有交集
4. 获取两集合的交集:intersection(),&
并集:union(),|
差集(A-B):difference(),-
对称差集{(A | B)-(A & B)}:symmetric_difference(),^
b1={10,20,30,40,80}
b2={10,50,30,20,60}
print(b1.intersection(b2))
print(b1 & b2)
print(b1.union(b2))
print(b1 | b2)
print(b1.difference(b2))
print(b1 - b2) #{80, 40}
print(b2.difference(b1))
print(b2 - b1) #{50, 60}
print(b1.symmetric_difference(b2))
print(b2 ^ b1) #{80, 50, 40, 60}
5. 集合的生成式:
{i*i for i in range(1,10)},没有元组生成式
ss={i*i for i in range(1,10)}
四、字符串
在Python中字符串是基本数据类型,是一个不可变的序列
1. 字符串的驻留机制:
仅保存一份相同且不可变字符串的方法,不同的值被存放在字符串的驻留池中,Python的驻留机制对相同的字符串只保留一份拷贝,后续创建相同字符串时,不会开辟新空间,而是把该字符串的地址赋给新创建的变量
驻留机制的几种情况(交互模式):
1.字符串的长度为0或1时
2.符合标识符的字符串
3.字符串只在编译时进行驻留,而非运行时
4.[-5,256]之间的整数数字
a='Python'
b="Python"
c='''Python'''
print(a,id(a)) #1671793907760
print(b,id(b)) #1671793907760
print(c,id(c)) #1671793907760
2. 字符串的查询操作方法:
1.index():查找子串substr第一次出现的位置,如果不存在,抛出ValueError异常
2.rindex():查找子串substr最后一次出现的位置,如果不存在,抛出ValueError异常
3.find():查找子串substr第一次出现的位置,如果不存在,则返回-1
4.rfind():查找子串substr最后一次出现的位置,如果不存在,则返回-1
s1='hello,hello'
print(s1.index('o'))
print(s1.rindex('o'))
# print(s1.index('1')) 报异常
print(s1.find('1'))
3. 字符串的大小写转换:
1.upper():把字符串中所有字符转换成大写
2.lower():把字符串中所有字符转换成小写
3.swapcase():把字符串中所有小写字符转换成大写,把字符串中所有大写字符转换成小写
4.capitalize():把第一个字符转换成大写,把其余字符转换成小写
5.title():把每个单词的第一个字符转换成大写,把每个单词的其余字符转换成小写
s2='HeLLoo WorLD'
print(s2.upper())#HELLOO WORLD
print(s2.lower())#helloo world 若原字符串全为小写,调用方法后仍会创建一个新的地址存储
print(s2.swapcase())#hEllOO wORld
print(s2.capitalize())#Helloo world
print(s2.title())#Helloo World
4. 字符串内容对齐:
1.center():居中对齐,第一个参数指定宽度,第二个参数
2.ljust():左对齐
3.rjust():右对齐
4.zfill():右对齐,用0进行填充
s3='hello,Python'
print(s3.center(20,'*'))
print(s3.ljust(5,'*'))
print(s3.rjust(20,'*')) #********hello,Python
print(s3.zfill(20))
5. 字符串的劈分:
1.split():
2.rsplit():从右侧开始劈分
s4='hello\ world\ python'
list1=s4.split()
print(list1)
print(s4.split(sep='d'))#当遇到d时,把d换成劈开符“,”
print(s4.split(sep='\ ',maxsplit=2))#['hello', 'world', 'python']
list2=s4.rsplit()#从右侧开始劈分
print(list2)
print(s4.rsplit(sep='\ ',maxsplit=1))#['hello\\ world', 'python']
5. 判断字符串:
1.isidentifier():判断指定的字符串是不是合法的标识符
2.isspace():判断指定的字符串是否全部由空白字符组成(回车,换行,水平制表)
3.isalpha():判断字符串是否全部由字母组成
4.isdecimal():判断指定字符串是否全部由十进制的数字组成
5.isnumeric():判断字典字符是否全部由数字组成
6.isalnum():判断指定字符串是否全部由字母和数字组成
print("abc".isalpha())
6. 字符串的替换,合并
字符串的替换:replace()
字符串的合并:join()
s='hello,9595'
print(s.replace('9595','hhhhhh')) #用'hhhhhh'替换'9595'
lis=['12','15','63']
print('a'.join(lis))#12a15a63,用a连接lis列表
print('*'.join('Hello'))#H*e*l*l*o
7. 字符串的比较:
比较原理:两字符串比较时,比较的是其原始值,调用内置函数ord()可以得到指定字符串的原始值,而对应的chr,调用内置函数chr时指定的原始值可以得到其对应的字符[原始值即为字符的ASCALL码值]
print('fllp'=='fllp')
print(ord('A'))
print(chr(65))
print('apple'>'banana') #False
8. 格式化字符串:
1.%占位符
2.{}作占位符 调用format函数
3.f-string
name='xst'
age=18
print("我叫%s,今年%10.3f" % (name,age))#我叫xst,今年 18.000。10表示宽度,.3表示保留小数点后3位数
print("我叫{0},今年{1}".format(name,age))#我叫xst,今年18
print(f"我叫{name},今年{age}")#我叫xst,今年18
五、函数
1. 函数的创建和调用:
函数就是执行特定任和以完成特定功能的一段代码
函数的创建:
def 函数名([形式参数]):
函数体
[return xxx]
函数调用:函数名([实际参数])
def sum(a,b): #此处a,b称为形式参数,形参出现的位置是函数定义处
c=a+b
return c
a=input("请输入第一个数:")
b=input("请输入第二个数:")
c=sum(a,b) #此处位置传参,a,b称为实际参数,实参出现的位置是函数调用处
print(c) #1030
d=sum(b=a,a=b) #等号左侧的变量名称称为关键字参数,根据形参名进行实参传递
print(d) #3010
2. 函数参数的传递:
在函数调用过程中,函数参数的传递:
1.如果是不可变对象,在函数体的修改不会影响实参的值,例如下列arg1=100不会影响n1的值
2.如果是可变对象,在函数体的修改会影响实参的值,例如下列arg2.append(10)会影响n2的值
def pri(arg1,arg2):
print("arg1:", arg1)
print("arg2:", arg2)
arg1=100
arg2.append(10)
print("arg1:", arg1)
print("arg2:", arg2)
n1=20
n2=[20,53,45]
print(n1,n2) #20 [20, 53, 45]
pri(n1,n2)
print(n1,n2) #20 [20, 53, 45, 10]
3. 函数的返回值:
1.若函数没有返回值,return可以不写
2.如果是一个,直接返回类型
3.若是多个,返回的结果为元组
def fun(num):
odd=[]
even=[]
for i in num:
if i%2: #i%2等价于i%2!=0 非0即为真
odd.append(i)
else:
even.append(i)
return odd,even
print(fun([10,6,50,26,15,30,24,13])) #([15, 13], [10, 6, 50, 26, 30, 24])
4. 函数参数的定义:
1.默认值参数
2.可变个数的位置参数:使用*定义且只能定义一个,结果为一个元组,print()函数即为个数可变的位置参数,将序列中的每个参数都转移到位置实参传入需要使用*定义实际参数
3.个数可变的关键字形参:使用**定义只能定义一个,结果为一个字典,将字典中的每个键值对都转换为关键字形参需要使用**定义实际参数
在一个函数的定义过程中,若既有个数可变的关键字形参,又有个数可变的位置形参,要求:个数可变的位置形参在个数可变的关键字形参前面
def dd(a,b=10): # b=10称为默认参数值
print(a,b)
dd(100) #若不给与形参赋值,则用默认值
dd(12,32) #给了就用实参值
def aa(*args):
print(args)
aa(21) #(21,)
aa(12,30,50)
def bb(**args):
print(args)
bb(a=21) #{'a': 21}
bb(a=12,b=30,c=50)
def cc(*arge1,**arge2):
pass
list=[10,20,65]
def ff(a,b,c):
print(a,b,c)
ff(*list) #ff(list)报错。将序列中的每个参数都转移到位置实参传入需要使用*定义实际参数
list1={'a': 10,'b':20,'c':30}
def gg(a,b,c):
print(a,b,c)
gg(**list1) #gg(list)报错。将字典中的每个键值对都转换为关键字形参需要使用**定义实际参数
5. 变量的作用域:
局部变量:在函数内定义并使用的变量,只在函数内部有效,局部变量使用global声明,这个变量就会成为全局变量
全局变量:函数体外定义的变量,可作用于函数内外
c,d=10,20#c,d为全局变量
def qq(a,b):
sum=a+b #c为局部变量,a,b相当于局部变量
print(sum)
print(c) #全局变量可在函数体内调用
global e #在函数体内定义,但是用global声明了,就变成了全局变量
e=52
print(d)
qq(c,d)
print(e)
6. 递归函数:
递归函数:在一个函数体内调用了函数本身,每递归调用一次函数,待会在栈内存分配一个栈帧,每次执行完一次函数,都会释放相应的空间
1.组成部分:递归调用与终止条件
2.缺点:占用内存多,效率低下
3.优点:思路和代码简单
例1:使用递归计算阶乘
#使用递归计算阶乘
def fun0(n):
if n==0 or n==1: #终止条件
return 1
else:
return fun0(n-1)*n
print(fun0(4))
例2:斐波那契数列
#斐波那契数列:1 1 2 3 5 8 13....
def fib(n):
if n==1 or n==2:
return 1
else:
return fib(n-1)+fib(n-2)
for i in range(1,8):
print(fib(i),end='\t')
#1 1 2 3 5 8 13