由于while只能通过下标进行循环,不过有些容器是没有下标的,不能用while循环。
所以设计出来了for循环,Python中的for本质是用来迭代容器中的每一个元素的!!!
而不是在C,Java理解的那个循环。
列表[]:和数组有点像,不过更像是数据结构中的list。
里面可以包含多个元素。
我们来看下具有下标的:
>>> ["1","2","3"]
['1', '2', '3']
>>> users = ['1','2','3']
>>> users
['1', '2', '3']
>>> users[1]
'2'
>>> users[0]
'1'
>>> users[2]
'3'
首先我们在users中存储了三个元素。
接下来我们使用循环将其进行输出:
>>> len(users)
3
>>> i = 0
>>> while i < len(users):
... print(users[i])
... i += 1
...
1
2
3
>>>
此时是具有下标的情况,而我们往往在之后不知道元素具体的位置,我们又该怎么办呢?比如说哈希表。
这时我们引入了for循环,当然for循环我们可以在有序中使用也可以在无序中使用。
简单来演示下for循环的使用方法:
for 临时变量 in(所属运算符) 容器 :
print(临时变量) #每一个迭代出来的元素
例如:
>>> for user in users:
... print(user)
...
1
2
3
>>>
range全局函数:
range(nujm)
** #[0,num)区间内的所有整数**
我们实际操作来观察下:
>>> range(10)
range(0, 10)
>>> for i in range(10):
... print(i)
...
0
1
2
3
4
5
6
7
8
9
>>>
range(start , end)
#[start,end)区间内的所有整数
比如说我们要求10到20之间的数的和包含10以及20
实现代码:
>>> s = 0
>>> for i in range(10,21):
... s += i
...
>>> s
165
>>>
那如果说我们要求10到20包含10但不包含20:
>>> s = 0
>>> for i in range(10,20):
... s += i
...
>>> s
145
>>>
这个就是关于两个参数。
那如果我们要三个参数的,比如1,3,5······
range(start,end,step) #默认步长是1,但是可以通关第三个参数修改步长那个。
比如我们接下来求0到100的偶数:
>>> for x in range(0,101,2):
... print(x)
...
0
2
4
6
8
10
12
14
16
18
20
22
24
26
28
30
32
34
36
38
40
42
44
46
48
50
52
54
56
58
60
62
64
66
68
70
72
74
76
78
80
82
84
86
88
90
92
94
96
98
100
>>>
步长可以填负数,那便是自减。
比如我们求1到100的和:
方法一:
>>> s = 0
>>> for i in range(101):
... s += i
...
>>> s
5050
方法二:
>>> s = 0
>>> for i in range(100,0,-1):
... s += i
...
>>> s
5050
>>>
接下来我们使用for循环进行打印:
题目1:
*
**
***
****
*****
实现代码:
layer = int(input("请输入您要打印的层数"))
for i in range(1,layer + 1):
for j in range(i):
print("*",end = "")
print()
输出结果:
D:\soft\pythonworkplace>test.py
请输入您要打印的层数5
*
**
***
****
*****
D:\soft\pythonworkplace>
题目2:
*
***
*****
*******
*********
实现代码:
layer = int(input("请输入您要打印的层数:"))
for i in range(layer):
for j in range(2 * i + 1):
print("*",end = "")
print()
输出结果:
D:\soft\pythonworkplace>test.py
请输入您要打印的层数:5
*
***
*****
*******
*********
D:\soft\pythonworkplace>
题目3:
*
**
***
****
*****
实现代码:
layer = int(input("请输入您要打印的层数:"))
for i in range(1,layer + 1):
space_name = layer - i
for j in range(space_name):
print(" ",end = "")
for j in range(i):
print("*",end = "")
print()
输出结果:
D:\soft\pythonworkplace>test.py
请输入您要打印的层数:5
*
**
***
****
*****
D:\soft\pythonworkplace>
这道题同样可以进行简化代码:
layer = int(input("请输入您要打印的层数:"))
for i in range(1,layer + 1):
print(" " * (layer - i),end = "")
print("*" * i)
输出结果:
D:\soft\pythonworkplace>test.py
请输入您要打印的层数:6
*
**
***
****
*****
******
D:\soft\pythonworkplace>
题目4:
*
***
*****
*******
实现代码:
layer = int(input("请输入您要打印的层数:"))
for i in range(1, layer + 1):
for j in range(layer - i):
print(" ",end = "")
for j in range(2 * i - 1):
print("*",end = "")
print()
输出结果
D:\soft\pythonworkplace>test.py
请输入您要打印的层数:5
*
***
*****
*******
*********
D:\soft\pythonworkplace>
题目5:
*******
*****
***
*
实现代码:
layer = int(input("请输入您要打印的层数:"))
for i in range(layer,0,-1):
for j in range(layer - i):
print(" ",end = "")
for j in range(2 * i - 1):
print("*",end = "")
print()
输出结果:
D:\soft\pythonworkplace>test.py
请输入您要打印的层数:5
*********
*******
*****
***
*
D:\soft\pythonworkplace>
题目6:
*
***
*****
*******
*********
*******
*****
***
*
实现代码:
layer = int(input("请输入您要打印的层数:"))
while layer % 2 == 0:
layer = int(input("请输入奇数行"))
for i in range(0,layer // 2 + 1):
print(" " * (layer - i),end = "")
print("*" * (2 * i + 1))
for i in range(layer // 2,0,-1):
print(" " * (layer - i + 1),end = "")
print("*" * (2 * i - 1))
输出结果:
D:\soft\pythonworkplace>test.py
请输入您要打印的层数:11
*
***
*****
*******
*********
***********
*********
*******
*****
***
*
D:\soft\pythonworkplace>
题目7:
*
* *
* *
* *
* *
* *
*
实现代码:
layer = int(input("请输入您要打印的层数:"))
while layer % 2 == 0:
layer = int(input("请输入奇数行"))
for i in range(0,layer // 2 + 2):
print(" " * (layer - i),end = "")
for j in range(2 * i + 2):
if j == 0 or j == 2 * i:
print("*",end = "")
else:
print(" ",end = "")
print()
for i in range(layer // 2,-1,-1):
print(" " * (layer - i),end = "")
for j in range(2 * i + 1):
if j == 0 or j == 2 * i:
print("*",end = "")
else:
print(" ",end = "")
print()
输出结果:
D:\soft\pythonworkplace>test.py
请输入您要打印的层数:11
*
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
* *
*
D:\soft\pythonworkplace>
题目8:
*
***
* * *
* * *
* * *
* * *
*************
* * *
* * *
* * *
* * *
***
*
实现代码:
layer = int(input("请输入您要打印的层数:"))
while layer % 2 == 0:
layer = int(input("请输入奇数行"))
for i in range(0,layer // 2 + 2):
print(" " * (layer - i),end = "")
for j in range(2 * i + 1):
if j == 0 or j == 2 * i or j == i or i ==layer // 2 + 1:
print("*",end = "")
else:
print(" ",end = "")
print()
for i in range(layer // 2,-1,-1):
print(" " * (layer - i),end = "")
for j in range(2 * i + 1):
if j == 0 or j == 2 * i or j == i:
print("*",end = "")
else:
print(" ",end = "")
print()
输出结果:
D:\soft\pythonworkplace>test.py
请输入您要打印的层数:11
*
***
* * *
* * *
* * *
* * *
*************
* * *
* * *
* * *
* * *
***
*
D:\soft\pythonworkplace>
1.1 什么叫做函数?
编程看来,函数其本质就是一个功能代码的集合。
函数本质就是现实中行为动作的代名词;
具有名称的功能代码的集合
1.2 python中函数如何定义:
使用关键字def
【该关键字就是用来定义函数的】
defined function
def 函数名称([参数列表...]):
# 函数体 由一行或者多行代码组成
# [return 返回值]
1.3 案例:
在控制上输出三句你好
实现代码:
# 实现一个函数,在控制台上输出你好
def say_hello():
print("你好")
print("你好")
print("你好")
输出结果:
D:\soft\pythonworkplace>test.py
D:\soft\pythonworkplace>
1.4 这里我们又为什么没有输出结果呢?
这里我们可以把函数理解为功能,这里它的功能也就是输出三句你好;然则你也可以有很多的功能;但是,功能的实现我们肯定是建立在需求之上的, 也就是我们构建了多个函数,有很多的功能,而这些功能呢?我们肯定不是每时每刻都要用到,所有函数本身是不进行执行的,同时,我们也进行学习了函数本身的功能也就是实现功能的复用。
所以当函数定义完成之后我们就要进行调用函数。
[返回值 = ]函数名称([参数列表])
C:\Users\lenovo>python
Python 3.11.3 (tags/v3.11.3:f3909b8, Apr 4 2023, 23:49:59) [MSC v.1934 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> help(print)
Help on built-in function print in module builtins:
print(*args, sep=' ', end='\n', file=None, flush=False)
Prints the values to a stream, or to sys.stdout by default.
sep
string inserted between values, default a space.
end
string appended after the last value, default a newline.
file
a file-like object (stream); defaults to the current sys.stdout.
flush
whether to forcibly flush the stream.
>>> print()
所以上一个案例的完整代码:
# 实现一个函数,在控制台上输出你好
def say_hello():
print("你好")
print("你好")
print("你好")
# 调用函数
say_hello()
此时我们来看输出结果:
D:\soft\pythonworkplace>test.py
你好
你好
你好
D:\soft\pythonworkplace>
好的,这里我们改变案例要求,我想要输出别人的基本信息,而print自己的基本信息不能进行修改;
所以此时我们可以进行改变下:
# 实现一个函数,在控制台上输出你好
def say_hello(name,age,address,gender):
print(f"我叫{name}")
print(f"我今年{age}岁")
print(f"我是一个来自{address}的{gender}")
# 调用函数
say_hello()
输出结果:
D:\soft\pythonworkplace>test.py
Traceback (most recent call last):
File "D:\soft\pythonworkplace\test.py", line 573, in <module>
say_hello()
TypeError: say_hello() missing 4 required positional arguments: 'name', 'age', 'address', and 'gender'
D:\soft\pythonworkplace>
这里我们的很显然的可以看出我们并没有给他们传name,age,address,gender
这四个值,所以:
# 实现一个函数,在控制台上输出你好
def say_hello(name,age,address,gender):
print(f"我叫{name}")
print(f"我今年{age}岁")
print(f"我是一个来自{address}的{gender}")
# 调用函数
say_hello("1",16,"陕西西安","男生")
say_hello("2",17,"陕西渭南","女生")
say_hello("3",18,"陕西延安","女生")
输出结果:
D:\soft\pythonworkplace>test.py
我叫1
我今年16岁
我是一个来自陕西西安的男生
我叫2
我今年17岁
我是一个来自陕西渭南的女生
我叫3
我今年18岁
我是一个来自陕西延安的女生
D:\soft\pythonworkplace>
这里上面案例进行阐述了有参数以及没有参数的案例。
所以,下面我们来一起看下有返回值的函数:
案例要求:输出x和y的和
实现代码:
def add(x,y):
return x + y
add(10,20)
这里我们可以看到输出结果:
D:\soft\pythonworkplace>test.py
D:\soft\pythonworkplace>
输出结果并没有,这又是什么原因?
我们首先来测试函数是否进行执行了:
实现代码:
def add(x,y):
print("函数执行了吗")
return x + y
add(10,20)
输出结果:
D:\soft\pythonworkplace>test.py
函数执行了吗
D:\soft\pythonworkplace>
这里我们可以看到函数是执行了的。
这里其实已经是返回了一个结果,我们只是没有进行接收这个值,所以:
def add(x,y):
return x + y
res = add(10,20)
print(res)
输出结果:
D:\soft\pythonworkplace>test.py
30
D:\soft\pythonworkplace>
下面我们来看下函数的分类。
1、局部变量(local variable
):又叫做本地变量,定义在函数内部的变量
局部变量只能在当前定义的函数内部有效
2、全局变量(global variable
):直接定义在模块中的变量,叫做全局变量
在python中,函数内部不允许修改全局变量!!!!
3、实际练习:
# 全局变量
name = "张三"
age = 16
def work_1(msg,show):
# a就是一个局部变量
a = 20
# 全局变量可以直接在函数内部访问
print(name)
print(age)
print(a)
a += 10
print(a)
work_1("哦","聊天止于哦哦")
这里我们来猜想下输出结果:
D:\soft\pythonworkplace>test.py
张三
16
20
30
D:\soft\pythonworkplace>
好,那么我们此时进行分步访问测试:
首先我们进行全局变量的访问:
name = "张三"
age = 16
def work_1(msg,show):
a = 20
print(name)
print(age)
print(a)
a += 10
print(a)
work_1("哦","聊天止于哦哦")
print(name)
print(age)
输出结果:
D:\soft\pythonworkplace>test.py
张三
16
20
30
张三
16
D:\soft\pythonworkplace>
我们可以看到我们可以在外界正常访问到全局变量;
接下来我们来访问a的值:
name = "张三"
age = 16
def work_1(msg,show):
a = 20
print(name)
print(age)
print(a)
a += 10
print(a)
work_1("哦","聊天止于哦哦")
print(name)
print(age)
print(a)
输出结果:
D:\soft\pythonworkplace>test.py
张三
16
20
30
张三
16
Traceback (most recent call last):
File "D:\soft\pythonworkplace\test.py", line 600, in <module>
print(a)
^
NameError: name 'a' is not defined
D:\soft\pythonworkplace>
我们可以看到这里只有a是没有正常访问到的,报错了。
变量a没有被定义。
下面我们接着改变案例的要求,这里要输出张三长了一岁的年龄:
name = "张三"
age = 16
def work_1(msg,show):
a = 20
print(name)
print(age)
print(a)
a += 10
print(a)
age += 1
print(age)
work_1("哦","聊天止于哦哦")
print(name)
print(age)
# print(a)
输出结果:
D:\soft\pythonworkplace>test.py
张三
Traceback (most recent call last):
File "D:\soft\pythonworkplace\test.py", line 599, in <module>
work_1("哦","聊天止于哦哦")
File "D:\soft\pythonworkplace\test.py", line 590, in work_1
print(age)
^^^
UnboundLocalError: cannot access local variable 'age' where it is not associated with a value
D:\soft\pythonworkplace>
我们可以看到这里报错了,又是什么原因呢?
这里它的意思是找不到局部变量age。
这又是什么原因呢?
正常情况,python拒绝在函数中修改全局变量,但是考虑到特殊情况下的需求,python中如果要修改全局变量,需要提前声明!!!!
如果说我们此时加上一个局部变量age:
name = "张三"
age = 16
def work_1(msg,show):
age = 1
a = 20
print(name)
print(age)
print(a)
a += 10
print(a)
age += 1
print(age)
work_1("哦","聊天止于哦哦")
print(name)
print(age)
# print(a)
输出结果:
D:\soft\pythonworkplace>test.py
张三
1
20
30
2
张三
16
D:\soft\pythonworkplace>
我们可以看到内部输出的age最后加了1,而最终输出的age值依然为我们定义的值16。
下面这个便是全局变量确实需要修改的时候,我们则需要在其使用内部加上声明global:
关键字 global 来声明
name = "张三"
age = 16
def work_1(msg,show):
global age
a = 20
print(name)
print(age)
print(a)
a += 10
print(a)
age += 1
print(age)
work_1("哦","聊天止于哦哦")
print(name)
print(age)
# print(a)
输出结果:
D:\soft\pythonworkplace>test.py
张三
16
20
30
17
张三
17
D:\soft\pythonworkplace>
a = 10
def test():
b = 230
print("hello")
test()
那么我们来猜想下电脑执行代码的过程:
内存是一个缓冲设备;
这里我们在第一节课讲到过;
内存中存在着堆以及栈,对象都是放在堆中,栈是一种线性结果,先进后出FILO以及后进先出LIFO。
与栈相对立的为队列:先进先出,后进后出。
程序为什么要建立这种结构?
首先我们来思考下我们创建执行栈而不创建执行队列?
假如我们有以下一串代码?
a = 10
b = a + 10
如果说我们创建的是队列,那么我们最终想要访问b的值,而a已经出去了,则访问不到了;栈的话则不一样,它会在执行b = a + 10之前将a = 10存进去。
然而当我们将所有的都往里面放,内存则会被撑爆了。也从而导致内存溢出。
下面我们接着分析;
在python中,函数本质也是一种对象!!!!!
对象则会存在堆里面,栈空间有限。
我们将函数的地址存在了栈中,和C中指针有点像。
程序调用的:本质就是将函数临时压入执行栈!!!
也就是我们将test函数压入栈中进行执行,当执行完最后一行代码就会立即进行弹栈操作,以避免长时间占用内存。
这里我们就可以理解为什么局部变量不能够被外面访问到,因为函数执行完毕立即弹栈,栈已经不存在局部变量的值了。
形参是局部变量
我们来看下面这串代码:
def change(a,b):
a += 10
b += 30
print(a,b)
x = 100
y = 200
print(x,y)
change(x,y)
print(x,y)
下面我们来看输出结果:
D:\soft\pythonworkplace>test.py
100 200
110 230
100 200
D:\soft\pythonworkplace>
这里也很好理解。
a和b这里只是局部变量,我们只进行了将x以及y的值分别赋予给了a以及b,也就是值传递,函数内部修改不会影响x以及y因为这是一个值传递。
下面我们来看下一串代码:
def change(a,b):
a += 10
b += 30
print(a,b)
x = 100
y = 200
print(x,y)
change(x,y)
print(x,y)
def add(nums):
nums.append(100)
nums.append(200)
print(nums)
ages = [10,20,30]
print(ages)
add(ages)
print(ages)
输出结果:
D:\soft\pythonworkplace>test.py
100 200
110 230
100 200
[10, 20, 30]
[10, 20, 30, 100, 200]
[10, 20, 30, 100, 200]
D:\soft\pythonworkplace>
这里我们可以看到,我们最终将100以及200存了进去。
这又是什么原因呢?
ages在这里也就是对象,对象我们都是存放在堆中的,堆中地址则存在了栈中,而这里add则传递的是地址,也就相当于nums变量拿到的是ages的存放堆中的地址,也就相当于指向了这一变量,而这里ages则将值存了进去,那么nums也会将100以及200存到这个地址中去。
# (默认值、可变、关键字参数)
def func_name([arge...])
# 函数体
# [return 返回值]
练习,求圆的周长以及面积。
在这之前,我们首先知道一个东西:帮助文档:
>>> help(print)
Help on built-in function print in module builtins:
print(*args, sep=' ', end='\n', file=None, flush=False)
Prints the values to a stream, or to sys.stdout by default.
sep
string inserted between values, default a space.
end
string appended after the last value, default a newline.
file
a file-like object (stream); defaults to the current sys.stdout.
flush
whether to forcibly flush the stream.
>>>
我们一般给函数进行标注注释一般在函数的上方,而python不一样,这里必须在函数定义下面的第一行,比如:
def get_circle_area():
"""
求圆的面积
"""
pass
print(help(get_circle_area))
输出结果:
D:\soft\pythonworkplace>test.py
Help on function get_circle_area in module __main__:
get_circle_area()
求圆的面积
None
D:\soft\pythonworkplace>
这里none代表返回值为空。
而这里我们打印了所有,我们如果想要打印帮助文档:
def get_circle_area():
"""
求圆的面积
"""
pass
print(get_circle_area.__doc__)
输出结果:
D:\soft\pythonworkplace>test.py
求圆的面积
D:\soft\pythonworkplace>
好,我们接着看求圆的面积:
def get_circle_area(r,PI):
"""
求圆的面积
"""
return r * r * PI
r1 = float(input("请输入圆的半径:"))
print(get_circle_area(r1,3.14))
输出结果:
D:\soft\pythonworkplace>test.py
请输入圆的半径:2
12.56
D:\soft\pythonworkplace>test.py
请输入圆的半径:3
28.26
D:\soft\pythonworkplace>
默认值参数:
如果函数中的某个或者某些参数,在调用时大多数情况下,是一个固定值。
为了调用方便,可以设定默认值。
默认值参数一定要写在普通值参数之后,否则会报错。
如果一个值在大多数情况下取一个值,我们可以默认给他一个值,比如这里PI大多数情况下使用3.14,则:
def get_circle_area(r,PI=3.14):
"""
求圆的面积
"""
return r * r * PI
r1 = float(input("请输入圆的半径:"))
print(get_circle_area(r1))
输出结果:
D:\soft\pythonworkplace>test.py
请输入圆的半径:4
50.24
D:\soft\pythonworkplace>
当然,如果我给了PI另一个值,那么他肯定是使用给定值,如果没有才采用默认值:
def get_circle_area(r,PI=3.14):
"""
求圆的面积
"""
return r * r * PI
r1 = float(input("请输入圆的半径:"))
print(get_circle_area(r1))
print(get_circle_area(r1,3.1415926))
输出结果:
D:\soft\pythonworkplace>test.py
请输入圆的半径:3
28.26
28.2743334
D:\soft\pythonworkplace>
可变参数:
*变量 这种形式定义的,注意:不是C语言中指针
它主要用来存储额外的参数!!!!,会将参数封装到元组中
依然是上一个案例,我们如果说想要进行加入别的功能,我们可以进行加入函数,当然,python中也可以加入可变参数。加上*arges不影响原来的代码,可以给他不进行传值。
def test(x,y,*args):
print(x + y)
test(2,5)
test(2,3,4,5,6,7)
输出结果:
D:\soft\pythonworkplace>test.py
7
5
D:\soft\pythonworkplace>
这里我们可以看到,我们给它进行多传几个值依然不会影响原来的代码,但是,最终执行的功能我们可以看到进行多个输入,它只传前面两个值,,从而输出了5.
而这里我们加入arges又有什么用呢?
def test(x,y,*args):
print(args)
print(x + y)
test(2,5)
test(2,3,4,5,6,7)
输出结果:
D:\soft\pythonworkplace>test.py
()
7
(4, 5, 6, 7)
5
D:\soft\pythonworkplace>
这里我们可以看到里面存进了4567,也就是你传了多余的参数他会把这些存进去。扩展了程序的功能也不影响原有的代码。
def test(x,y,*args):
if len(args) > 0:
print(args[0])
print(x + y)
test(2,5)
test(2,3,4,5,6,7)
输出结果:
D:\soft\pythonworkplace>test.py
7
4
5
D:\soft\pythonworkplace>
所以,我们可以看下print函数:
>>> help(print)
Help on built-in function print in module builtins:
print(*args, sep=' ', end='\n', file=None, flush=False)
Prints the values to a stream, or to sys.stdout by default.
sep
string inserted between values, default a space.
end
string appended after the last value, default a newline.
file
a file-like object (stream); defaults to the current sys.stdout.
flush
whether to forcibly flush the stream.
>>>
这里面我们就可以明确的看到print里面第一个就是可变参数,因此它可以直接传入多个值。
命名参数:
又叫做关键字参数
**变量
可变参数和关键字参数,主要的功能就是配合装饰器进行功能扩展的!!!
就比如:
>>> help(print)
Help on built-in function print in module builtins:
print(*args, sep=' ', end='\n', file=None, flush=False)
Prints the values to a stream, or to sys.stdout by default.
sep
string inserted between values, default a space.
end
string appended after the last value, default a newline.
file
a file-like object (stream); defaults to the current sys.stdout.
flush
whether to forcibly flush the stream.
>>> print("hello","world",end = "")
hello world>>> print("hello","world",end = "",sep = "+")
hello+world>>>
这里我们可以看到print函数有着end以及分割sep关键字参数。
下面我们依旧是那个案例:
def test(x,y,*args,**kwargs):
if len(args) > 0:
print(args[0])
print(kwargs)
print(x + y)
test(2,5)
test(2,3,4,5,6,7,a = 123,b = 456,name = "xxx",age = 16)
输出结果:
D:\soft\pythonworkplace>test.py
{}
7
4
{'a': 123, 'b': 456, 'name': 'xxx', 'age': 16}
5
D:\soft\pythonworkplace>
{'a': 123, 'b': 456, 'name': 'xxx', 'age': 16}
这个我们叫做字典。
我们也试着去拿值:
def test(x,y,*args,**kwargs):
if len(args) > 0:
print(args[0])
if len(kwargs) > 0:
print(kwargs["name"])
print(x + y)
test(2,5)
test(2,3,4,5,6,7,a = 123,b = 456,name = "xxx",age = 16)
输出结果:
D:\soft\pythonworkplace>test.py
7
4
xxx
5
D:\soft\pythonworkplace>
函数作为参数传递函数内部:
python中函数是对象,python中函数的参数只要是对象即可,所以pyhton中函数可以作为参数传递到函数内部。
注意如下两种情况的不同之处:
def a()
pass
def b()
pass
b(a) # 函数作为参数传递到函数中
b(a())# 将a的返回值作为参数传递到函数中
案例:
def demo(fn):
# 下面这行代码就是一个函数调用
# fn是一个函数
fn("hello,函数你好")
demo(print)
输出结果:
D:\soft\pythonworkplace>test.py
hello,函数你好
D:\soft\pythonworkplace>
那么我们可不可以加括号?
def demo(fn):
# 下面这行代码就是一个函数调用
# fn是一个函数
fn("hello,函数你好")
demo(print())
输出结果:
Traceback (most recent call last):
File "D:\soft\pythonworkplace\test.py", line 657, in <module>
demo(print())
File "D:\soft\pythonworkplace\test.py", line 655, in demo
fn("hello,函数你好")
TypeError: 'NoneType' object is not callable
D:\soft\pythonworkplace>
这又是什么意思呢?
这里我们也就是等同于如下代码,首先执行调用。
def demo(fn):
# 下面这行代码就是一个函数调用
# fn是一个函数
fn("hello,函数你好")
print(print())
demo()
输出结果:
D:\soft\pythonworkplace>test.py
None
Traceback (most recent call last):
File "D:\soft\pythonworkplace\test.py", line 658, in <module>
demo()
TypeError: demo() missing 1 required positional argument: 'fn'
D:\soft\pythonworkplace>
我们可以看到首先print(print())执行结果为none,然后我们在进行了调用,此时进行报错,也就是none不能被调用。
这里我们也可以进行联想到,print实际存储在堆里面,而栈里面存储的则是print的引用地址。所以我们也就是将print的引用地址传给了fn,从而输出了一段i字符串。
当然,这里直接使用print输出函数可以,同时我们也可以自己构建一个函数进行函数传递:
def demo(fn):
# 下面这行代码就是一个函数调用
# fn是一个函数
fn("hello,函数你好")
def print_msg(msg):
print(msg)
demo(print_msg)
输出结果:
D:\soft\pythonworkplace>test.py
hello,函数你好
D:\soft\pythonworkplace>
这里可以看到输出结果是一样的。
所以,python中函数是可以以参数的形式存入函数内部的。带了括号相当于传了函数的返回值。函数带括号表示函数调用,不带括号表示函数引用,代表函数本身。
匿名函数:没有名称的函数,不能直接调用
python
在lambda
引入之前是没有匿名函数的!
lambda
表达式之后,才通过lambda
实现了匿名函数
lambda(x,b,c):函数体
同样是以上案例:
def demo(fn):
# 下面这行代码就是一个函数调用
# fn是一个函数
fn("hello,函数你好")
demo(lambda msg:print(msg))
输出结果:
D:\soft\pythonworkplace>test.py
hello,函数你好
D:\soft\pythonworkplace>
这里lambda使用后面加参数这里也就是函数名,冒号后面加返回值,这里则为函数内容。
使用lambda主要用于匿名场景中,进行简化。
lambda本质是简化编写程序的难度!!!!!
可能存在某个函数,该函数中存在默认值
如果后面调用时,多次需要修改为一个相同的默认值【变成另外一个值】可以使用偏函数实现
我们可以看下int:
>>> help(int)
Help on class int in module builtins:
class int(object)
| int([x]) -> integer
| int(x, base=10) -> integer
|
| Convert a number or string to an integer, or return 0 if no arguments
| are given. If x is a number, return x.__int__(). For floating point
| numbers, this truncates towards zero.
|
| If x is not a number or if base is given, then x must be a string,
| bytes, or bytearray instance representing an integer literal in the
| given base. The literal can be preceded by '+' or '-' and be surrounded
| by whitespace. The base defaults to 10. Valid bases are 0 and 2-36.
| Base 0 means to interpret the base from the string as an integer literal.
| >>> int('0b100', base=0)
| 4
|
| Built-in subclasses:
| bool
|
| Methods defined here:
|
| __abs__(self, /)
| abs(self)
|
| __add__(self, value, /)
| Return self+value.
|
-- More --
我们可以看到base=10,这里int就是整型10进制不用改默认值。如果我们需要进行进制转换:
>>> int("123456")
123456
>>> int("123456",base = 10)
123456
>>> int("123456",base = 8)
42798
>>> int("11111",base = 2)
31
>>>
我们可以重新构建一个函数,只是这里不是10进制,而是二进制,引入functools模块。
1、import functools
functools.partial()
2、from functools import partial
# 返回一个新的函数 = partial(原函数, 默认值=新值)
使用:
>>> import functools
>>> dir(functools)
['GenericAlias', 'RLock', 'WRAPPER_ASSIGNMENTS', 'WRAPPER_UPDATES', '_CacheInfo', '_HashedSeq', '_NOT_FOUND', '__all__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', '_c3_merge', '_c3_mro', '_compose_mro', '_convert', '_find_impl', '_ge_from_gt', '_ge_from_le', '_ge_from_lt', '_gt_from_ge', '_gt_from_le', '_gt_from_lt', '_initial_missing', '_le_from_ge', '_le_from_gt', '_le_from_lt', '_lru_cache_wrapper', '_lt_from_ge', '_lt_from_gt', '_lt_from_le', '_make_key', '_unwrap_partial', 'cache', 'cached_property', 'cmp_to_key', 'get_cache_token', 'lru_cache', 'namedtuple', 'partial', 'partialmethod', 'recursive_repr', 'reduce', 'singledispatch', 'singledispatchmethod', 'total_ordering', 'update_wrapper', 'wraps']
>>> functools.partial
<class 'functools.partial'>
>>> from functools import partial
>>> partial(int,base=2)
functools.partial(<class 'int'>, base=2)
>>> a = partial(int,base=2)
>>> a
functools.partial(<class 'int'>, base=2)
>>> a("100")
4
>>> a("100",base=10)
100
>>> int("100")
100
>>>
递归(recursion
):函数自身调用自身,需要设置递归的终止条件
一定要有终止条件,否则是个死循环。
案例:求 0-n的和
# 求0-n的和
def get_count(n:int):
if n == 1:
return 1
return n + get_count(n - 1)
count = get_count(100)
print(f"0-100的和是{count}")
输出结果:
D:\soft\pythonworkplace>test.py
0-100的和是5050
D:\soft\pythonworkplace>
这里也就牵扯了压栈,弹栈。
这就是栈内进行大量调用执行从而占用大量空间。
这里我们可以尝试着让其调用1000多次:
# 求0-n的和
def get_count(n:int):
if n == 1:
return 1
return n + get_count(n - 1)
count = get_count(1000)
print(f"0-100的和是{count}")
输出结果:
D:\soft\pythonworkplace>test.py
Traceback (most recent call last):
File "D:\soft\pythonworkplace\test.py", line 668, in <module>
count = get_count(1000)
^^^^^^^^^^^^^^^
File "D:\soft\pythonworkplace\test.py", line 665, in get_count
return n + get_count(n - 1)
^^^^^^^^^^^^^^^^
File "D:\soft\pythonworkplace\test.py", line 665, in get_count
return n + get_count(n - 1)
^^^^^^^^^^^^^^^^
File "D:\soft\pythonworkplace\test.py", line 665, in get_count
return n + get_count(n - 1)
^^^^^^^^^^^^^^^^
[Previous line repeated 996 more times]
RecursionError: maximum recursion depth exceeded
D:\soft\pythonworkplace>
这里报错,递归错误,已经超过了递归最大数量。
同时,我们可以调用sys内置模块来看递归最大次数:
import sys
print(sys.getrecursionlimit())
# 求0-n的和
def get_count(n:int):
if n == 1:
return 1
return n + get_count(n - 1)
count = get_count(1000)
print(f"0-100的和是{count}")
输出结果:
D:\soft\pythonworkplace>test.py
1000
Traceback (most recent call last):
File "D:\soft\pythonworkplace\test.py", line 671, in <module>
count = get_count(1000)
^^^^^^^^^^^^^^^
File "D:\soft\pythonworkplace\test.py", line 668, in get_count
return n + get_count(n - 1)
^^^^^^^^^^^^^^^^
File "D:\soft\pythonworkplace\test.py", line 668, in get_count
return n + get_count(n - 1)
^^^^^^^^^^^^^^^^
File "D:\soft\pythonworkplace\test.py", line 668, in get_count
return n + get_count(n - 1)
^^^^^^^^^^^^^^^^
[Previous line repeated 996 more times]
RecursionError: maximum recursion depth exceeded
D:\soft\pythonworkplace>
当然,我们如果真的要求1到1000以上的和或者其他,我们也可以进行自己设置递归的次数,这里设置2000次最大次数,从而输出1到1500的求和:
import sys
# print(sys.getrecursionlimit())
sys.setrecursionlimit(2000)
# 求0-n的和
def get_count(n:int):
if n == 1:
return 1
return n + get_count(n - 1)
count = get_count(1500)
print(f"0-100的和是{count}")
输出结果:
D:\soft\pythonworkplace>test.py
0-100的和是1125750
D:\soft\pythonworkplace>
练习: 1、求斐波那契数列的第n项值
实现一个函数,求斐波那契数列的第n项值
斐波那契数列:从第三项开始,每一项的值是前两项之和
a[n] = a[n - 1] + a[n - 2]
1 1 2 3 5 8 13 21 34 55 89 ……
实现代码:
def fibonacii(n: int) -> int:
if n == 1 or n == 2:
return 1
return fibonacii(n - 1) + fibonacii(n - 2)
print(fibonacii(10))
输出结果:
D:\soft\pythonworkplace>test.py
55
D:\soft\pythonworkplace>
2、跳楼梯问题:
f(n)=f(n-1)+f(n-2)
实现代码:
def staircase(n):
if n == 1 or n == 2:
return n
return staircase(n - 1) + staircase(n -2)
print(staircase(10))
输出结果:
D:\soft\pythonworkplace>test.py
89
D:\soft\pythonworkplace>
3、不死兔子问题:
小明得到了一对兔子
1 1 1 1 2 3 4 5 7 10 14 19 26 36
a[n] = a[n - 1] + a[n - 4]
实现代码:
def rabbit(n):
"""
求不死兔子数量
"""
if n <= 4:
return 1
else:
return rabbit(n - 1) + rabbit(n -2)
print(rabbit(8))
输出结果
D:\soft\pythonworkplace>test.py
8
D:\soft\pythonworkplace>
容器本质就是用来存储大量数据的一种数据结构
容器篇:
list
set
tuple
dict
线性表:
指的是一种有顺序的存储表
list
):stack
):FILO LIFO
queue
)FIFO LILO
list(列表)
注意: python中的列表底层是使用双向链表实现的!!!
判断以下哪些不能作为标识符
A、a
B、¥a
C、_12
D、$a@12
E、false
F、False
输入数,判断这个数是否是质数(要求使用函数 + for循环)
实现代码:
um = int(input("请输入一个整数:"))
def work_1(num):
flag = True
for i in range(2,num // 2 + 1):
if num % i == 0:
flag = False
break
if flag:
print(f"{num}为质数")
else:
print(f"{num}为合数")
work_1(num)
求50~150之间的质数是那些?
实现代码:
def work_9():
for num in range(50,101):
for i in range(2,num):
if num % i == 0:
break
else:
print(num)
work_9()
4打印输出标准水仙花数,输出这些水仙花数
实现代码:
def work_10():
for a in range(1,10):
for b in range(0,10):
for c in range(0,10):
num = a * 100 + b * 10 + count
if num == a ** 3 + b ** 3 + c ** 3:
print(num)
work_10()
验证:任意一个大于9的整数减去它的各位数字之和所得的差,一定能被9整除.
实现代码:
def work_2(num):
for i in range(9,num):
if (num - num % 10) & 9 == 0:
return True
return False
for i in range(100):
if work_2(i):
print(f"{i}可以被整除")
一个五位数,若在它的后面写上一个7,得到一个六位数A,
若在它前面写上一个7,得到一个六位数B,B是A的五倍,求此五位数.
实现代码:
def work_4():
for i in range(10000,100000):
a = i * 10 + 7
b = 7 *100000 +i
if b == a * 5:
return i
print(get(num))
求十进制数字的二进制编码:求十进制数字的二进制编码中的1的数量
实现代码:
求1~100之间不能被3整除的数之和
实现代码:
def work_5():
sum = 0
for i in range(1,101):
sum += i
sum1 = 0
for j in range(1,101):
if j % 3 != 0:
sum1 = j
sum1 += j
sum2 = sum - sum1
print(f"1~100之间不能被3整除的数之和:{sum2}")
work_5()
给定一个正整数N,找出1到N(含)之间所有质数的总和
实现代码:
num = int(input("请输入一个正整数:"))
def work_6(N):
sum = 0
for i in range(1,N+1):
for j in range(2,i // 2 + 1):
if i % j == 0:
break
sum += i
print(f"所有质数的总和:{sum}")
work_6(num)
计算PI(公式如下:PI=4(1-1/3+1/5-1/7+1/9-1…)
实现代码:
num = int(input('请输入正整数n:'))
def work_7(n):
x = 0
a = 0
for i in range(1 , n+1 , 2):
x += 1 / i * (-1) ** a
a += 1
print("PI的近似值:",4 * x)
work_7(n)
求a+aa+aaa+…+aaaaaaaaa=?其中a为1至9之中的一个数,项数也要可以指定
实现代码:
def work_8(n):
count = 0
num = 0
for i in range(n):
num += n * 10 ** i
count += num
return count
num = int(input("请输入一个1到9的整数:"))
print(work_8(num))
找出10000以内能被5或6整除,但不能被两者同时整除的数(函数)
实现代码:
不死兔子和跳楼梯问题
实现代码:
汉诺塔问题
实现代码: