文章一览
- 一 、顺序结构
- 二、分支结构
- 多分支结构
- 三、循环结构
- 1. for语句循环结构
- range()函数
- 2. while语句构成循环
- 1)while 循环流程
- 3、for 循环和 while 循环的区别
- 4、for 循环和 while 循环效率比较
- 四、函数
- 1、函数定义
- 1) 内置函数
- 2) 非内置函数
- 3)自定义函数
- 2、函数的优点
- 3、**函数-结构化设计方法**
- 4、函数参数
- **参数调用方式**
- 1)位置参数
- 2) 关键字参数
- 3)混合参数调用
- 4)默认参数
- 5)不定长参数
- 6) 拆分序列(容器)型实参
- (1)列表、元组拆分:实参前加 *,拆分为位置参数
- (2)字典拆分:实参前加 `**`,拆分为关键字参数
- (3)函数头部混合 一般参数、* 以及 ** 参数
1966年 G.Jacopini 和 C.Bohm 在“Communications of the ACM”发表了一篇论文:“Flow diagrams, turing machines and languages with only two formation rules”.
从理论上证明了,任何程序都可以用 三 种基本的结构来表达:
- 顺序结构
- 分支结构
- 循环结构
一 、顺序结构
顺序结构语句是程序中最基础的语句。赋值语句、输入/输出语句、模块导入语句等都是顺序结构语句。
二、分支结构
并非所有的程序语句都要被顺序执行,有时希望满足某种条件就执行这部分语句,满足另一条件就执行另一部分语句,这就需要“条件分支语句”。
为了使程序能够根据条件执行不同的语句,通常需要判断一个布尔值
多分支结构
三、循环结构
循环,从广义上说是一个周期现象或者重复出现的情况,这种状态称为循环。
对程序语言来说,就是在满足某种条件的情况下,反复执行某一段代码。这段代码称为循环体,循环通常是用来解决复杂问题的必备结构。在 python中有 for 循环和 while 循环这两种结构。它们的应用场景不太一样,但是它们都可以完成相同的功能。
1. for语句循环结构
for variable in object:缩进语句块(循环体)
依次遍历对象(object)中的每个元素,并赋值给 variable(循环变量),然后执行循环体内语句。
for 比较适合于循环次数确定的情况
语 法:
for variable in iterable_object:statements(要重复执行的语句)
所谓可迭代就是可以按顺序依次返回变量中的元素,它的值是可以遍历的。
iterable_object:
- range 函数
- string
- list
- tuple
- dictionary
- file
可以明确循环的次数:
- 遍历一个数据集内的元素;
- 在列表等可迭代对象中使用;
range()函数
range 是python语言的内置函数,所谓内置函数是我们可以直接调用的。Range 函数可以产生一组有规律的数据
语法:
range (start,end,step = 1)
range (start,end)
range (end)
start: 计数从 start 开始。默认是从 0 开始。例如 range(5)等价于range(0,5);
end:计数到 end 结束,但不包括 end。例如:range(0,5)是 [0, 1, 2, 3, 4 ] 没有 5;
step:步长,默认为 1。例如:range(0,5) 等价于 range(0, 5, 1);
2. while语句构成循环
循环语句第二种结构是 while 循环结构
while 循环和 if 语句的结构很相像,那么这两个之间有什么区别呢?
区别在于,if 语句只会执行一次判断条件,条件成立以后,仅执行一次代码块;而 while语句,会先执行一次判断条件,如果条件成立就会执行一次代码块,代码块执行完成以后,会再次判断条件语句。如果还成立,将会再执行代码语句… 一直到最后条件不成立。
1)while 循环流程
- 循环体外设定循环可执行的初始条件
- 设定循环条件
- 书写需重复执行的代码(循环块语句)
- 在循环体内设定条件改变语句
例题:提示用户输入密码,密码不正确则提示不正确,正确则提示成功,然后结束
while (input('请输入密码:')!= 'cau'):print("密码不正确!")
print("芝麻开门了,成功!")
3、for 循环和 while 循环的区别
for in 循环是用来循环特定数据结构的,比如可迭代对象 string、list、tuple、dict。循环(迭代)次数可知
因此 for 语句常用于能够预先判断循环次数的循环或遍历中。如遍历一个字符串或列表,或者执行某操作若干次。此时用 for 语句较优。
while 语句的历史更久,表达方式上更自由灵活,常用于无法事先判断循环次数的循环,while 循环主要用在需要满足一定条件为真,反复执行的情况。
最后强调,两者从表达能力上说是等价的,即两者能够完成的事情是一样的,能够预先判断循环次数的流程用 for、while 都能实现,但无法预先判断循环次数的流程用 while 实现较好。
4、for 循环和 while 循环效率比较
在做数据分析时,经常需要对时间数据进行处理,在 python中,处理时间数据的库主要有下面三个:time
、datetime
以及 calendar
时间模块 time 是内置模块,它内部封装了一些获取时间戳和字符串形式时间的函数, 时间戳是指从计算机元年到现在经过的秒数。计算机元年是指 1970年1月1日0时0分0秒。
import time
#获取当前时间戳
t = time.time()
print(t)import time
#获取格式化时间对象,返回值是当前格林尼治时间
t = time.gmtime()import time
#获取当地(北京)时间
t = time.localtime()
while 实际上比 for 多执行了两步操作:
- 循环条件检查
- 变量 i 的自增
在任何语言中,循环都是一种非常消耗时间的操作。假如任意一种简单的单步操作耗费的时间为 1 个单位,将此操作重复执行上万次,最终耗费的时间也将增长上万倍
实现循环的最快方式 —— 就是不用循环!
Python 底层的解释器和内置函数是用 C 语言实现的,而 C 语言的执行效率远大于 Python。
四、函数
1、函数定义
z = f ( x , y , … ) z=f(x,y,…) z=f(x,y,…)
- 函数可以看成类似于数学中的函数,有 函数名、自变量 和 因变量
- 函数定义是一种将较大问题分解为较小问题的方法
- 完成一个特定功能的一段代码,这段代码可以作为一个单位使用,并且给它取一个名字(函数名)
- 通过函数名执行
- 函数分 内置函数、非内置函数 和 自定义 函数
1) 内置函数
函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段
内置函数是系统提供的,可以直接使用: dir(__builtins__)
2) 非内置函数
内置 函数可以直接使用。那么 非内置 函数如何使用呢?
使用时首先要把它的 模块 导入(**import)**进来
对于所有需要 import
使用的代码统称为函数库。利用函数库编程的方式称为 “模块编程”。
导入模块的方法:
有两种导入模块的方法:
- import 模块名
- from 模块名 import *
import math ,调用 math 里的 函数 或 属性值 时需要在前面加 math.
而 from math import* 则不用在函数前面加 math
>>> import math
>>> math.sqrt(25)
5.0
>>> math.pi
3.141592653589793
>>> from math import *
>>> sqrt(16)
4.0
>>> pi
3.141592653589793
可以导入多个模块
import ModuleName1, ModuleName2,...
导入某个模块指定的属性或函数
from math import sin
sin(30)
需要注意的是,库(模块)函数也分为 内置 库和 非内置 库,非内置 库(也称第三方库)需要安装。
3)自定义函数
**实例:**求 1+2+3+。。。10 的值
result = 0
for i in range (1,11):result = result + i
print (result)
自定义计算累加和的函数
调用函数
def num_sum (start,stop):result = 0for i in range(start,stop + 1):result = result + ireturn results = eval(input())
t = eval(input())
print (num_sum (s,t))
如何定义一个函数:
- 函数代码块以 def 关键词开头,后接函数标识符名称和圆括号()
- 任何传入参数和自变量必须放在圆括号中。圆括号之间可以用于定义参数
- 函数内容以 冒号 起始,并且 缩进
- return [表达式] 结束函数,选择性地返回一个值给调用方
不带表达式的 return 相当于返回 None
函数变量作用域:
函数变量分两类:全局变量 和 局部变量
全局变量
为整个程序所使用的变量
所有函数均可使用
局部变量
只能在程序的特定部分使用的变量
函数内部使用
# 局部变量
def num_sum (start,stop):result = 0for i in range(start,stop + 1):result = result + is = eval(input('s = '))
t = eval(input('t = '))
num_sum (s,t)
print (result)
# 全局变量
def num_sum (start,stop):global resultresult = 0for i in range(start,stop + 1):result = result + is = eval(input('s = '))
t = eval(input('t = '))
num_sum (s,t)
print (result)
2、函数的优点
-
代码可重用
-
提高开发效率
-
减少编码程序
-
-
编程更容易把握
-
可以把程序分成较小部分
-
化繁为简
-
-
代码更简洁
- 函数功能相对独立,功能单一
- 结构清晰,可读性好
-
封装与信息隐藏
- 不必关心内部实现细节
- 降低耦合关系
3、函数-结构化设计方法
4、函数参数
函数,在定义的时候,可以有参数的,也可以没有参数
函数 参数 处理机制是 Python 中一个非常重要的知识点
def greet(name):print(f"Hello, {name}!")
# 调用函数
greet("Alice")# 计算斐波那契数列的前10项
def print_fibonacci():a, b = 0, 1for _ in range(10):print(a, end=' ')a, b = b, a + bprint() # 打印换行
# 调用函数
print_fibonacci()
随着 Python的 演进,参数处理机制的灵活性和丰富性也在不断增加,不仅可以写出简化的代码,也能处理复杂的调用
从函数定义的角度来看,参数可以分为两种:
- 必选参数:调用函数时必须要指定的参数
- 可选参数:也叫默认参数,调用函数时可以指定也可不指定,不指定就是默认的参数值
参数调用方式
从函数调用的角度来看,参数可以分为以下三种:
- 位置参数:调用时,不使用关键字参数的 key-value 形式传参,这样传参要注意按照函数定义时参数的顺序来
- 关键字参数:调用时,使用 key = value 形式传参的,这样传递参数就可以不按定义顺序来
- 混合参数:位置参数和关键字参数混合使用
1)位置参数
大多数情况下,调用函数时,实参向形参的传递是按照位置一一对应进行的,就是按参数的位置进行调用
def f(a,b,c):print(a,b,c)
f(1,2,3)
2) 关键字参数
可以忽略参数位置顺序,直接指定参数
def f(a,b,c):print(a,b,c)
f(c=4,a=2,b=3)
可以看出,当关键字参数使用时参数从左至右的关系已不再重要了,因为参数是通过变量名进行传递的,而不是通过其位置
3)混合参数调用
位置参数和关键字参数混合调用
def f(a,b,c):print(a,b,c)
f(1,c=3,b=2)
可以看出,基于位置的参数和基于关键字的参数混合使用也可以。
在这种情况下,所有基于位置的参数首先按照从左到右的顺序匹配头部的参数,之后再进行基于变量名进行关键字的匹配。
4)默认参数
定义函数时,可以对一个或多个参数指定默认值
def f(a,b=2,c=3):print(a,b,c)
f(1)
必须为 a 提供值,无论是通过位置参数还是关键字参数来实现, 但是,为 b 和 c 提供值是可选的。如果不给 b 和 c 传递值,它们会分别赋值为 2 和 3。(缺省参数)
函数在定义时,必选参数一定要在可选参数的前面,不然运行时会报错。
5)不定长参数
调用函数时,让形参接收任意数量的实参(可以是 0 个或者任意个),这样的形参称为不定长参数
传参时不能指定参数名,通常使用 *args 和 **kw 来表示
- *args:接收到的所有按照位置参数方式传递进来的参数,是一个元组类型
- **kw :接收到的所有按照关键字参数方式传递进来的参数,是一个字典类型
>>> def f(*args, **kw):
>>> print(args)
>>> print(kw)
>>> f(10, 20, c=20, d=40)
(10, 20)
{'c': 20, 'd': 40}
>>> def f(a,*args):
>>> print(args)
>>> f(1,2,3,4)
(2, 3, 4)>>> def add(a,b,*args):
>>> c = a + b
>>> for i in args:
>>> c = c + i
>>> return c
>>> print(add(1,2))
3
>>> print(add(1,2,3,4))
10
6) 拆分序列(容器)型实参
如果一个函数所需要的实参已经存储在了列表、元组或字典中,则可以直接将数据从列表、元组或字典中拆分出来
(1)列表、元组拆分:实参前加 *,拆分为位置参数
>>> def add(*args):
>>> sum = 0
>>> for i in args:
>>> sum = sum + i
>>> return sum
>>> lis = [3,4,5,6]
>>> print('求和结果为:', add(*lis))
求和结果为: 18
通过一个元组给一个函数传递四个参数,并且让 python 将它们解包成不同的参数:
>>> def func(a,b,c,d):
>>> print(a,b,c,d)
>>> args = (1,2,3,4)
>>> func(*args)
1 2 3 4
(2)字典拆分:实参前加 **
,拆分为关键字参数
**
符号只对关键字参数有效。实参前加 **
,拆分为关键字参数
以两个星号 ** 为前缀的参数 kwargs 表示可以将关键字参数转化为字典, kwargs 就是这个字典的名称
>>> def f(**kw):
>>> print(kw)
>>> f(a=1,b=2)
{'a': 1, 'b': 2}
(3)函数头部混合 一般参数、* 以及 ** 参数
>>> def f(a, *args, **kargs):
>>> print(a,args,kargs)
>>> f(1,2,3,x=4,y=5)
1 (2, 3) {'x': 4, 'y': 5}
例子中,1 按位置传给 a,2 和 3 收集到 args 位置的元组中,x 和 y 放入 kargs 关键字词典中
如果 ** 语法出现在函数调用中又会如何呢?
>>> def func(a,b,c,d):
>>> print(a,b,c,d)
>>> kargs = {'a':1, 'b':2, 'c':3,'d':4}
>>> func(**kargs)
1 2 3 4
在函数调用时,** 会以键值对的形式解包一个字典,使其成为独立的关键字参数
四种参数类型可以在一个函数中出现,但一定要注意顺序
>>> def demo_func(arg1, arg2=10, *args, **kw):
>>> print("arg1: ", arg1)
>>> print("arg2: ", arg2)
>>> print("args: ", args)
>>> print("kw: ", kw)
>>> demo_func(1,12, 100, 200, d=1000, e=2000)
arg1: 1
arg2: 12
arg3: (100, 200)
arg4: {'d': 1000, 'e': 2000}
使用单独的 *,当在给后面的位置参数传递时,对传参的方式有严格要求,在传参时必须要以关键字参数的方式传参数,要写参数名,不然会报错
>>> def demo_func(a, b, *, c):
>>> print(a)
>>> print(b)
>>> print(c)
>>> demo_func(1, 2, 3)
报错
>>> demo_func(1, 2, c=3)
1
2
3