8、类型转换、深浅拷贝
8.1 数据转换
数据类型
- int 整型 float浮点数 bool 布尔值 complex复数
- str 字符串
- list 列表
- tuple 元组
- dict 字典
- set 集合
# 类型转换
int()
num = int("123")
if num == 123:
print("等于123")
num = 123
n = str(num) #转换为字符串
print(type(n))
# eval() 用来执行一个字符串表达式,并返回表达式的值
res = eval("10+10")
print(res) #得到20
res = eval("[1,2,3]")
print(type(res)) # 转换为list
b = list("abc")
c = tuple(b) #转换为元组
print(c)
op = {} #这是字典
print(type(op)) # <class 'dict'>
op2 = set() #集合类型
op2 = set("abcdefg") #集合类型
print(type(op2)) #集合
# 转换为字典
li = ["name","age"]
value = ["zhangsan",18]
dic = dict(zip(li,value))
li = [('name','zs'),('age',18)]
dic = dict(li)
8.2 浅拷贝
前言:数据赋值
li = [1,2,3]
li2 = li
li.append(4)
print(li2) #对li修改,li2也跟着修改
浅拷贝(数据半共享):会创建新对象,拷贝第一层的数据,嵌套层会指向原来的内存地址
外部不同,但是内部是相同的
import copy
a = [1,2,[3,4]] # [3,4] 指的是嵌套层
b = copy.copy(a)
print(a,id(a)) #通过id来查看变量a的地址
print(b,id(a))
# a和b是不同的。
a.append(5)
print(a) #[1,2,[3,4],5]
print(b) #[1,2,[3,4]]
a[2].append(5) # 给嵌套列表中插入数据
print(a) # [1,2,[3,4,5],5]
print(b) # [1,2,[3,4,5]]
8.3 深拷贝
深拷贝:数据完全不共享,a和b完全独立
import copy
a = [1,2,[3,4]]
b = copy.deepcopy(a)
print(a)
print(b)
b.append(5)
print(a) # [1,2,[3,4],5]
print(b) # [1,2,[3,4]]
a[2].append(5)
print(a) # [1,2,[3,4,5],5]
print(b) # [1,2,[3,4]]
8.4 可变对象与不可变对象
可变对象:存储的对象可以被修改
常见的可变类型:
- 列表 list
- 字典 dict
- 集合 set
不可变对象
- int
- bool
- float
- complex
- str 字符串
- tuple 元组
# 不可变对象
# 不可以修改,修改相当于重新给一个值
n = 10
print(n)
print(id(n)) #查看内存地址
n += 1
print(id(n)) # 内存地址不一样
st = "hello"
print(id(st)) #查看内存地址
st = st + 'python'
print(id(st)) #内存地址不同
tu = (1,2,3)
print(id(tu))
# 可变 list/dict/set
# 变量对应的值可以修改,但是内存地址保持不变
li = ['上九天揽月','床前明月光']
print(id(li))
li.append('张三')
print0(id(li)) #两个内存地址不会改变
dic = {"name":"张三","age":18}
print(dic)
print(id(dic))
dic["name"] = "吃花椒"
print(id(dic))
9 函数基础
9.1 函数
函数的定义:
def 函数名():
函数体
9.2 函数的返回值
return 给函数的调用者返回值,函数中遇到return,此函数不再继续执行
9.3 函数的参数
函数的参数有必选参数、默认参数、可变参数、关键字参数
- 必选参数: 写几个就传几个 def funa(a,b)
- 默认参数: def funa(a=12)
- 可变参数: 将实参所有的位置参数接收,放在一个元组里 def funa(* args)
- 关键字参数: 接受所有的关键字参数,将其转换为一个字典。 def funa(**kwargs)
9.4 函数的嵌套
def funa():
def funb():
print("这是内部函数")
funb()
funa()
可变参数
def fun(a,b,*c,d=5):
print(a)
print(b)
print(c)
print(d)
fun(1,2,3,4,7)
# 输出结果
# 1
# 2
# (3,4,7)
# 5
def fun1(a,b):
return a+b
fun1(*(1,2))
# 返回3
fun1(*[1,2])
# 返回3
fun1(*{1,2})
# 返回3
10 函数进阶
1.定义函数def 返回值return 2.函数参数,预备参数,默认参数,可变参数 3.函数嵌套 在一个函数中调用一个函数,在一个函数中定义一个函数
10.1 作用域
10.1.1 作用域的概念
局部变量
只在函数内部有作用
从定义位置开始到函数定义结束位置有效
全局变量
函数外部定义的变量整个范围有效
price = 2
def st1():
print(f"全局变量{price}")
def st2():
print(f"全局变量{price}")
# 输出结果
# 2
# 2
price = 2
def st1():
print(price)
def st2():
price=1.2
print(price)
print(price)
st1()
st2()
print(price)
#输出结果
2
2
1.2
2
# 因为函数内部用变量,现在里面找,里面找不到再到外面找
全局变量和局部变量相同
a = 100
def funa():
a = 200 #局部变量
print(a)
# 输出结果
200
# 当局部变量和全局变量相同的时候,优先使用局部变量
10.1.2 global
如何修改全局变量
global 将变量提升为全局变量
global 将会修改全局变量
global 将变量名声明为全局变量
a = 100
def funa():
global a
print(a)
a = 200
print(a)
## 输出结果为
## 200
## 200
global name 将局部变量name变成了全局变量
def speak():
global name ,num
name = "jiuge"
print(name)
def work():
print(num)
speak()
print(name)
10.1.3 nonlocal
nonlocal 外层函数的局部变量,只能在嵌套函数中使用
使用与global类似
将变量声明为外层变量(外层函数的局部变量,而且不能是全局变量)
def out_fun():
num = 10
def inner_fun():
nonlocal num
num = 20
inner_fun()
print(num)
out_fun()
# 输出结果
# 20
def out_fun():
a = 10
def inner1():
a = 5
def inner2():
nonlocal a
a = 20
print(a)
inner2() #调用函数
print(a)
inner1()
print(a)
#输出结果
# 20
# 20
# 10
10.2 匿名函数
语法: 函数名 = lambda 形参:返回值
lambda是定义匿名函数的关键字,相当于函数的def
调用: 结果 = 函数名(实参)
def funa(a,b):
return a+b
funa(1,2)
# 等价于
res = lambda a,b : a+b
res(1,2)
n1 = 5
n2 = 8
# 如果if条件为真,就打印为print(n1)
print(n1) if n1 < n2 else print(n2) #三目运算符
we = lambda n1,n2: "正确" if n1<n2 else "错误"
print(we(1,2))
10.3 内置函数
10.3.1 max,min,range方法
比如说max,min,range等系统自带的内置函数
#查看所有的内置函数
import builtins
print(dir(builtins))
abs(17) #返回绝对值
sum([1,2,3]) #求和
min
zip
10.3.2 zip函数
a = [1,2,3]
b = [4,5,6,5]
for i in zip(a,b):
print(i)
# 输出结果
# (1,4)
# (2,5)
# (3,6)
10.3.3 reduce函数
## reduce方法
# 求和
from functools import reduce
res = reduce(lambda x,y : x+y , [1,2,3,4,5])
# 求积
from functools import reduce
res = reduce(lambda x,y:x*y , [1,2,3,4,5])
#求阶乘 求5!
from functools import reduce
res = reduce(lambda x,y:x*y , range(1,6))
10.3.4 map函数
# ============
l = [1,2,3]
def funa(x)
return x+3
mp = map(funa,l) #依次作用到列表中的每个元素上,保存到新的list之中
print(list(mp))
# 返回结果 [4,5,6]
# ===================
# 通过map给每个元素开平方
res = map(lambda x : x*x , [1,2,3,4,5])
res = list(res)
#得到结果
#[1,4,9,16,25]
10.4 拆包
# 拆包
li = [1,2,3,5]
a,*b = li
print(a)
print(b)
# 输出结果
# 1
# [2,3,5]
# ======================
# =======================
tu = (1,2,3,4)
a,b,c,d = tu
print(a,b,c,d)
# 输出结果
# 1,2,3,4
#=====================
a,*b,c = [1,2,3,4,5]
print(a)
print(b)
print(c)
# 输出结果
# 1
# [2,3,4]
# 5
*a,b = [1,2,3]
print(a)
print(b)
# 输出结果
# [1,2]
# 3
l = {"姓名":1, "名称":2}
*a,b = l
print(a)
print(b)
# 输出结果
# ['姓名']
# 名称
10.5 递归函数
概念:一个函数在内部不调用其他的函数,而是调用本身
自己调用我自己
递归函数的要点
- 必须要有一个明确的结束条件
- 每进行更深一层的递归时,问题规模相比上次都要有所减少
- 相邻两次重复之间有紧密的联系
# 计算1-20的累加和
def add():
s = 0
for i in range(1,21):
s += i
print(s)
def funa(n):
if n==1:
return 1
else:
return n + funa(n-1)
print(funa(5))
#求斐波那契数列
def fib(n):
if n==2 or n==1:
return 1
else:
return fib(n-1)+fib(n-2)
print(fib(5))
10.6 闭包
在嵌套函数的前提下,内部函数使用了外部函数的变量,而且外部函数返回了内部函数
我们就把使用了外部函数变量的内部函数称为闭包
构成条件
- 函数中嵌套了一个函数
- 内存函数使用了外层函数的变量
- 外层函数的返回值是内层函数的函数名
def outer(): #外部函数
n = 10
def inner(): #内部函数
print(n) #内部函数用到了外部函数的变量
return inner
ot = outer() #这是一个函数
ot() #调用函数
def test():
print("打印test")
t = test
t() #相当于调用了test函数
def outer(m):
def inner(n):
return m+n
return inner
inn = outer(5)
inn(6)
# 返回结果
# 11
# 第二种方法
outer(5)(6)