第八节:集合&函数


在这里插入图片描述

深拷贝和浅拷贝

  • 不可变对象的拷贝
    不可变类型(如数字、字符串、元组)进行赋值,深浅拷贝,其对应内存地址ID也相等
# 不可变对象的拷贝就是对象赋值,浅拷贝和深拷贝是没有区别
import copy
a = 'Python'
b = a
c = copy.copy(a)
d = copy.deepcopy(a)
print('赋值:',id(b))   # 得 赋  值: 31336496
print('浅拷贝:',id(c)) # 得 浅拷贝: 31336496
print('深拷贝:',id(d)) # 得 深拷贝: 31336496
  • 因为我们这里操作的是不可变对象,Python 用引用计数的方式管理它们,所以 Python 不会对值相同的不可变对象,申请单独的内存空间。只会记录它的引用次数
  • 可变对象的拷贝
    可变对象的拷贝,会在内存中开辟一个新的空间来保存拷贝的数据。当再改变之前的对象时,对拷贝之后的对象没有任何影响。
import copy
l1 = [1,2,3]
l2 = copy.copy(list1)
print(id(l1)) # 得 1916636282952
print(id(l2)) # 得 1916636282952
list1[0] = 11
print(id(l1)) # 得 191663142088
print(id(l2)) # 得 1916636282952

原理图如下:
在这里插入图片描述

  • 浅拷贝
    copy() 函数在拷贝对象时,只是将指定对象中的所有引用拷贝了一份,如果这些引用当中包含了一个可变对象的话,那么数据还是会被改变。 这种拷贝方式,称为浅拷贝
    **优点:**拷贝速度快,占用空间少,拷贝效率高
a =[1,2]
l1 = [3,4,a]
l2 = copy.copy(l1)
print(id(l1)) # 得 1916631704520
print(id(l2)) # 得 1916631713736
a[0] = 11
print(id(l1)) # 得 1916631704520
print(id(l2)) # 得 1916631713736
print(l1) 	  # 得 [3, 4, [11, 2]]
print(l2) 	  # 得 [3, 4, [11, 2]]

原理图如下:
在这里插入图片描述

  • 深拷贝
    区别于浅拷贝只拷贝顶层引用,深拷贝会逐层进行拷贝,直到拷贝的所有引用都是不可变引用为止。
a =[1,2]
l1 = [3,4,a]
l2 = copy.deepcopy(l1)
print(id(l1)) # 得 1916632194312
print(id(l2)) # 得 1916634281416
a[0] = 11
print(id(l1)) # 得 1916632194312
print(id(l2)) # 得 1916634281416
print(l1) 	  # 得 [3, 4, [11, 2]]
print(l2) 	  # 得 [3, 4, [1, 2]]

原理图如下:
在这里插入图片描述

总结

  • 1.由于 Python 内部引用计数的特性,对于不可变对象,浅拷贝和深拷贝的作用是一致的,就相当于复制了一份副本,原对象内部的不可变对象的改变,不会影响到复制对象

  • 2.浅拷贝的拷贝。其实是拷贝了原始元素的引用(内存地址),所以当拷贝可变对象时,原对象内可变对象的对应元素的改变,会在复制对象的对应元素上有所体现

  • 3.深拷贝在遇到可变对象时,又在内部做了新建了一个副本。所以,不管它内部的元素如何变化,都不会影响到原来副本的可变对象

字典的遍历

集合的简介

• 集合表现形式set{} 集合和列表非常相似
• 不同点
• 集合只能存储不可变对象
• 集合中存储的对象是无序的
• 集合不能出现重复元素

集合的使用

  • 使用{}来创建集合
  • 可以通过set()来将序列和字典转换成集合
  • len() 使用len()来获取集合中元素的数量
  • add()像集合中添加元素
a=set()
a.add(1)
print(len(a)) # 得 1
print(a) 	  # 得 {1}
  • update()将一个集合中的元素添加到另一个集合当中
a={1,2,3,4,5,6,7}
b={9,13}
a.update(b)
print(a) # 得 {1, 2, 3, 4, 5, 6, 7, 9, 13}
  • pop()随机删除集合中的一个元素一般是删除最后一个元素
  • remove() 删除集合中指定的元素
  • clear() 清空集合

集合的运算

  • & 交集运算
  • | 并集运算
  • 一 差集运算
  • ^ 亦或集
  • <= 检查一个集合是否是另一个集合的子集
  • < 检查一个集合是否是另一个集合的真子集
  • ‘>=检查一个集合是否是另一个集合的超集
  • ’>检查一个集合是否是另一个集合的真超集
set1={2,4,3,6,21,32}
set2={4,3,82,5,24,35}
#交集
print(set1&set2)
#并集
print(set1|set2)
#差集
print(set1-set2)
#异或集
print(set1^set2)
运行结果:
{3, 4}
{32, 2, 3, 4, 5, 6, 35, 82, 21, 24}
{32, 2, 21, 6}
{2, 5, 6, 82, 21, 24, 32, 35}

可变和不可变类型数据

  • 可变对象: 列表、字典、集合
    所谓可变是指可变对象的值可变,身份是不变的。

  • 不可变对象:数字、字符串、元组
    不可变对象就是对象的身份和值都不可变。新创建的对象被关联到原来的变量名,旧对象被丢弃,垃圾回收器会在适当的时机回收这些对象。

var1 = "python"
id(var1)
1700782038408
#由于var1是不可变的,重新创建了java对象,随之id改变,旧对象python会在某个时刻被回收
var1 = "java"
id(var1) 
1700767578296

函数的简介

  • 函数也是一个对象
  • 函数用来保存一些可执行的代码,并且可以在需要时,对这些语句进行多次调用
语法
def 函数名([形参1,形参2,形参3....]):
    代码块

注意:
函数名必须符合标识符的规范(可以包含字母、数字、下划线但是不能以数字开头)
print是函数对象 print()是调用函数

函数的参数

  • 形参和实参
    • 形参(形式参数) 定义形参就相当于在函数内部声明了变量,但是并不是赋值
    • 实参(实际参数)指定了形参,那么在调用函数时必须传递实参,实参将会赋值给对应的形参,简单来说有几个形参就要有几个实参
def fun(a,b):
    print(a*b)
fun(3,5) # 得 15

参数的传递方式

  • 函数的传递方式
    • 定义形参时,可以为形参指定默认值。指定了默认值以后,如果用户传递了参数则默认值不会生效。如果用户没有传递,则默认值就会生效
# 当实参没传递参数时使用形参默认值,当传递参数时则会替换掉形参默认值
def fun(a,b,c=20):
    print(a*b*c)
fun(1,2) 	# 得 40
fun(1,2,3)  # 得 6

• 位置参数:位置参数就是将对应位置的实参赋值给对应位置的形参

def fun(a,b):
	print(a,b)
fun(2,3) # 得 2 3
fun(3,2) # 得 3 2

• 关键字参数 : 关键字参数可以不按照形参定义的顺序去传递,而根据参数名进行传递

# 位置传参和关键字传参可以混合使用,但位置传参必须放在关键字传参之前。
def fun(a,b,c):
    print(a,b,c)
fun(b=3,c=5,a=6) # 得 6 3 5 关键字参数根据参数名进行传递
fun(a=4,b=5,9) 	 # 报错9没定义,位置参要放关键字参之前,系统不知道要把9传给谁
fun(4,c=9,b=13)  # 得 4 13 9
fun(5,9,c=8)     # 报错,因为9不知道是要传给b还是a
fun(3,8,9)       # 得 3 8 9

• 混合使用位置参数和关键字参数的时候必须将位置参数写到关键字参数前面去

参数的类型

# 实参可以是任何类型
def fun(a):
    print(a)
fun('3')			# 得 3
fun(print(111)) 	# 得 111 None
fun([1,2,3,4,5])	# 得 [1, 2, 3, 4, 5]
fun({1,2,3,4,5})	# 得 {1, 2, 3, 4, 5}
fun(True)			# 得 True

作业

1.打印名片程序:输入姓名,电话号码,性别最后打印出名片 控制姓名长度为6-20,电话长度为11,性别只能输入男或女,每样信息不能为空。

# 位置传参法
def fun(ximing,tele,xinbie):
    while True:
        if len(ximing) < 6 or len(ximing) > 20:
            print('姓名长度为6-20,请你重新输入')
            if len(str(tele)) != 11:
                print('电话长度为11位,请你重新输入')
                if '男' or '女' not in xinbie:
                    print('性别只能输入男或女,请你重新输入')
                    continue
                continue
            continue
        else:
            print('*您的名片**********************')
            print('你的姓名:' + ' ' + ximing)
            print('你的电话号码:' + ' ' + str(tele))
            print('你的性别:' + ' ' + xinbie)
            print('*******************************')
            break
fun('happy2020',13950892321,'男')
运行结果:
*您的名片**********************
你的姓名: happy2020
你的电话号码: 13950892321
你的性别:*******************************

2.定义一个函数1-100和并打印结果

def sum(num):  
    i = 1      
    j = 0      
    while i <= 
        j += i 
        i += 1 
    print(j)   
sum(100)      # 得 5050

声明:本文为学习笔记,转载请标明出处,本文仅供交流学习,请勿用于非法途径,希望本文对大家有帮助。

仅是个人意见,如有不足之处或者侵权,请留言!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值