01. 语句介绍与顺序结构
- 语句是指在语法上自成体系的一个基本单位,在一般的编程语言中,语句结束的标记是“;”。
- 其实Python中语句也是以分号结束的,只不过Python建议是把分号省略掉。
- 但如果在一行中写了两条及以上的数量的语句,那语句间要用分号隔开。(几乎任何语言都不建议在一行中写多条语句)
- 顺序结构是一种代码的执行流程,指一个源码文件中所有的语句按照从上至下的顺序依次逐行解释执行。
顺序结构无法满足所有场景,如符合条件才执行、重复执行等场景。
02. 分支结构
2.1 分支语句概述
分支语句是指把可能出现的情况列出,满足哪个条件就执行对应的操作。
- 如按照中国的年龄分段:
- 0~6岁:你的阶段为童年。
- 7~17岁:你的阶段为少年。
- 18~40岁:你的阶段为青年。
- 41~65岁:你的阶段为中年。
- 66岁以后:你的阶段为老年。
Python提供的分支语句为if语句,有if单语句、if-else语句、if-elif-else语句三种格式。
2.2 三种分支结构
2.2.1 if结构
if单语句适用于满足某个条件就执行某些计算,不满足则维持原状的场景。
语法格式:
if 条件表达式:
条件表达式为True时执行的代码块
示例:出门逛街,有现金1000元,如果遇到 ATM机,则再取1000元。
money = 1000 # 现有现金1000元
meet_atm = False # 用于标记是否遇到ATM,True为遇到、False为没遇到
if meet_atm == True:
money += 1000 # 如果遇到,则再取1000元。
print(f"现有现金:{money:.2f}元")
2.2.2 if-else结构
if-else也被称之为双分支语句,适用于达到某个条件就做某件事,否则就做另外一件事情的场景。
- 简单来说就是如果达到某个条件,就做事情1,否则做事情2。
语法格式:
if 条件表达式:
条件表达式为True时执行的代码块
else:
条件表达式为False时执行的代码块
示例:输入一个年份,如果是闰年,则输出二月为29天,否则输出二月为28天。
- 提示:
- 闰年分为普通闰年和世纪闰年。
- 普通闰年:年份为4的倍数,单不是100的倍数。
- 世纪闰年:年份为400的倍数。
代码实现:
year = int(input("请输入年份:"))
if year % 4 == 0 and year % 100 != 0 or year % 400 == 0:
feb_days = 29
else:
feb_days = 28
print(f"二月为{feb_days}天")
运行结果: ```python
结果一
请输入年份:1967 二月为28天
结果二
请输入年份:2000 二月为29天
<a name="sdv15"></a>
#### 2.2.3 if-elif-else结构
- if-elif-else称为多分支结构,会罗列出多种情况,并执行唯一一种符合条件的情况。
- 当所列出的全部情况都不满足时,执行else中的代码块。
![多分支.png](https://cdn.nlark.com/yuque/0/2022/png/2692415/1659792804113-66fd4fc7-3134-4221-bf82-395a36f8aeb9.png#averageHue=%23fdfdfd&clientId=u3f80d642-85ee-4&from=paste&height=300&id=ube464cc8&originHeight=776&originWidth=1416&originalType=binary&ratio=1&rotation=0&showTitle=false&size=136046&status=done&style=none&taskId=u6e7264e6-f9a1-4ae8-a70d-56c50d81595&title=&width=547)
- 语法格式:(else可以没有,即if-elif结构)
```python
if 条件表达式1:
条件表达式1为True时执行的代码块
elif 条件表达式2:
条件表达式1为False,但是条件表达式2为True时执行的代码块
elif 条件表达式3:
条件表达式1和2都为False,但是条件表达式3为True时执行的代码块
elif ……
else:
所有条件表达式都为False时,执行的代码块
示例:实现2.1中中国的年龄分段程序。
age = eval(input("请输入您的年龄:"))
if 0 < age <= 6:
print("童年")
elif 7 <= age <= 17:
print("少年")
elif 18 <= age <= 40:
print("青年")
elif 41 <= age <= 65:
print("中年")
elif 66 <= age <= 150:
print("老年")
else:
print("请输入正确的年龄数据!")
2.2.4 分支语句嵌套
当满足某种逻辑的基础上,还需要再进行逻辑判断。
- 从语法上来说就是if语句里还有一层if语句。
比如:想要做公交车去上班,就需要经过两层if判断。
- 第一层:是否成功赶上公交车。
- 第二层:上车后,是否有足够的钱可以支付车费。
- 上车后其实还可以根据是否有空位,判断是坐着乘车还是站着乘车。
on_time = False # 标记是否准时
balance = 0.5 # 标记余额
have_seat = True # 标记公交车上是否有空的座位
if on_time:
if balance >= 1.5:
if have_seat:
print("您可以坐着乘车")
else:
print("您只能站着乘车")
else:
print("很遗憾,您的余额不够您乘车")
else:
print("很遗憾,您没有赶上公交车。")
2.3 三元运算符(if-else简写)
有些语言专门提供了三元运算符,其格式一般都为:
条件表达式 ? 表达式1 : 表达式2
(若条件表达式为True,则执行表达式1,否则执行表达式2)。- 但是Python在语法上并没有提供这种运算符,不过可以通过简写if-else语句来实现类似的结构。
- Python中的拟三元运算符结构:
表达式1 if 条件表达式 else 表达式2
(若条件表达式为True,则执行表达式1,否则执行表达式2)。 - 示例:获取两个数的最大值。 ```python num1 = float(input(“num1 = “)) num2 = float(input(“num2 = “))
if-else结构的写法
if num1 > num2: max_num = num1 else: max_num = num2 print(f”max num is {max_num}”)
拟三元运算符的写法
max_num = num1 if num1 > num2 else num2 print(f”max num is {max_num}”)
<a name="Rl3cs"></a>
## 03. 循环结构
<a name="e5SCZ"></a>
### 3.1 循环概述
- 循环就是重复执行某些操作,有以下两种场景:
- 达到某种状态后就可以跳出的循环。
- 无法停止的循环(也称死循环),程序中应该避免死循环。
- Python中有for循环(也称for-in循环)和while循环两种。
<a name="v0u8A"></a>
### 3.2 for-in循环
<a name="raJXo"></a>
#### 3.2.1 for-in循环概述与格式
- for-in循环主要用于遍历容器内的数据,将数据逐个取出并进行操作;还可以用于次数确定的循环。
- for-in循环的基本格式:
- in表示进入到容器内,判断是否有下一个元素。
- 如果有下一个元素,则将元素返回给变量名,并执行重复的操作,执行完成后再in下一个元素。
- 直到in没有下一个元素时,循环结束。
- 从这里可以得出一个结论,容器内有多少个元素,就会循环多少次。
```python
for 变量名 in 容器:
重复的操作
示例1:依次遍历字符串Hello中的每一个字符。
s = "Hello"
for i in s:
print(i)
示例2:依次遍历字符串HelLo, niCe tO MEET yoU.中的每一个字符,并打印出其中的小写字母。
s = "HelLo, niCe tO MEET yoU."
for i in s:
if "a" <= i <= "z":
print(i)
示例2:依次遍历字符串hello178good24中的每一个字符,并将其中的数字字符取出,组合成一个新的字符串。
s1 = "hello178good24"
s2 = ""
for i in s1:
if "0" <= i <= "9":
s2 += i
print(s2) # 17824
3.2.2 for i in range
range(end)
:生成[0, end - 1],步长为1的等差数列。 ```python for i in range(10): print(i, end=” “) # end参数:print参数打印后,再打印的内容。默认为\n,即换行。
运行结果:0 1 2 3 4 5 6 7 8 9
- `range(start, end)`:生成[start, end - 1],步长为1的等差数列。
```python
for i in range(5, 10):
print(i, end=" ")
# 运行结果:5 6 7 8 9
range(start, end, step)
:- step > 0:end必须大于start,生成[start, end - 1],步长为step的,递增的等差数列。 ```python for i in range(5, 50, 10): print(i, end=” “)
运行结果:5 15 25 35 45
- step < 0:end必须小于start,生成[start, end + 1],步长为step的,递减的等差数列。
```python
for i in range(50, 5, -1):
print(i, end=" ")
# 运行结果:50 40 30 20 10
- 若start和end没有按照规定谁大谁小,则range()会生成一个空区间。 ```python print(“=” 30) for i in range(1, 100, -3): print(i) print(“=” 30)
print(“=” 30) for i in range(100, 1, 3): print(i) print(“=” 30)
“””
运行结果:(说明range生成的是空数列,因此两个循环都执行0次。)
==============================
============================== “””
<a name="AXmY8"></a>
### 3.3 while循环
<a name="oAzgY"></a>
#### 3.3.1 while循环概述与格式
- while循环主要用于循环次数不明确,但明确循环条件的场景。
- 语法格式:
- 首先判断条件表达式是否为True。
- 若为True,则执行循环体内的代码;若为False,则不进入循环或者循环结束。
- 循环体内的代码执行完成后,会再判断一次条件表达式是否为True,以此类推,知道条件表达式为False为止。
```python
while 条件表达式:
循环体
- 注意点:
- 循环体代码内一般会对参与条件表达式运算的变量做出改变。
- 如果不改变参与条件表达式运算的变量,则条件表达式会一直为True,那么循环就变成了一个死循环。
while循环的实现要点:
示例一:一根绳子长3000米,每次减去绳子的三分之一,问要减多少次,绳子长度才不足5米。
length = 3000
count = 0
while length >= 5:
length *= 2/3
count += 1
print(length, count) # 4.56731652104233 16
示例二:一张纸的厚度为0.08毫米,问对折多少次才能达到8848.16米。
thickness = 0.08
flag_thickness = 8848160
count = 0
while thickness < flag_thickness:
thickness *= 2
count += 1
print(f"第{count}次对着,厚度为:{thickness / 1000}米")
3.4 跳出循环
3.4.1 循环跳出概述
通常情况下,循环语句会执行完所有的情况后自然会退出。
- 但也有些情况下,我们需要将当前正在执行的循环终止,也就是跳出循环。
跳出循环语句,包括跳出整个循环的break语句和放弃本次循环的continue语句。
3.4.2 break语句
break语句可以跳出离它最近一级的循环,能够用于for和while循环,且通常结合if语句判断,当满足某个条件时退出循环。
- 示例1:遍历名字字符Dosbo,当到s时退出循环。
```python
name = “Dosbo”
for i in name:
if i == “s”:
print(i, end=” “)break
运行结果:D o
- 示例2:打印1~9,但当打印5时,停止打印。
```python
i = 1
while i <= 9:
if i == 5:
break
print(i, end=" ")
i += 1
# 运行结果:1 2 3 4
注意:break跳出的是离他最近的一级循环,如果循环有嵌套,则内存循环的退出不会影响外层循环。
3.4.3 continue语句
continue语句用于跳出当前循环,并继续执行下一次循环。
- 当循环代码块中遇到continue时,系统会忽略当前循环中剩下的代码,从头开始下一次循环。
- 示例:找出列表
[0, -2, 5, 7, -10]
中所有的正数。 ```python for i in [0, -2, 5, 7, -10]: if i <= 0:
print(i, end=” “)continue
运行结果:5 7
- 注意:break和continue只能用在循环中,其他地方不能难度使用。
<a name="UX6pu"></a>
#### 3.4.4 pass语句
- pass语句表示不做任何事情,用于语法上必须有,但是程序什么也不做的场景。
- 由于Python没有使用花括号来标记代码块,无法使用花括号或者冒号来表示空代码。
- 因此有些要求必须有代码的语法场合,如果什么都不写,那么会直接报错,此时就可以用pass语句。
- 除此之外,pass还可以用来标记留待以后开发的代码,即可以当做占位符使用。
- 示例:先写一个循环,循环条件是a大于10,但循环体内具体写什么逻辑不知道,先空着。
```python
a = 20
while a > 10:
pass
04. 语句嵌套
- 在满足某种逻辑场景下,还需要再次进行循环或者判断才可以得到相对应的结果,这时候就需要在语句里再套一层语句。
- 不管是分支结构还是循环结构,都可以进行语句嵌套。
示例一:录入一个年份、月份,获取这个月份的天数。(分支语句嵌套)
year, month = map(int, input().split())
if month in (1, 3, 5, 7, 8, 10, 12):
print(f"{year}年{month}有31天")
elif month in (4, 6, 9, 11):
print(f"{year}年{month}有30天")
elif month == 2:
if year % 100 != 0 and year % 4 == 0 or year % 400 == 0:
days = 29
else:
days = 28
print(f"{year}年{month}有{days}天")
else:
print("月份不合法")
示例二:打印九九乘法表。(循环结构嵌套)
for i in range(1, 10):
for j in range(1, i + 1):
print(f"{j} * {i} = {i * j}", end="\t")
print()
05. random模块与string模块
5.1 模块的概念
一个Python文件是一个模块,Python中的模块分为三种:
- 官方自带模块:在Python安装目录下有个Lib目录,里面的文件就是官方自带的Python模块。
- 自定义模块:自己创建的”.py”文件。
- 第三方模块:由一些开发者或组织自行开发后上传到官网的模块。(需要使用pip工具安装)
模块在使用时需要导入,导入方式有两种:
random模块用于获取一些随机信息。
- choice()函数:这个函数的参数是一个容器类型的数据,他会随机抽取容器内的其中一个并返回。
```python
导入方式一
import random
从字符串”HelloWorld”随机获取一个字符
ch = random.choice(“HelloWorld”) print(ch)
导入方式二
from random import choice
从1~100中随机获取一个数。
num = choice(range(1, 101)) print(num)
- random()函数:在[0, 1)中随机返回一个小数。
```python
import random
num = random.random()
print(num)
randint()函数:在[start, end]中随机返回一个整数。(注意:这是唯一一个将结束位置元素包含在内的函数)
import random
num = random.randint(10, 20)
print(num)
5.4 string模块
string中有一些比较重要的字段:
- whitespace:ASCII码中所有的空白符号,值为:
' \t\n\r\v\f'
- ascii_lowercase:所有的小写英文字母,值为:
'abcdefghijklmnopqrstuvwxyz'
- ascii_uppercase:所有的大写英文字母,值为:
'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
- ascii_letters:所有的英文字母,值为:
ascii_lowercase + ascii_uppercase
- digits:所有的十进制数据字符,值为:
'0123456789'
- hexdigits:所有的十六进制数据字符,值为:
digits + 'abcdef' + 'ABCDEF'
- octdigits:所有的八进制数据字符,值为:
'01234567'
- punctuation:所有的特殊符号,值为:
r"""!"#$%&'()*+,-./:;<=>?@[\]^_
{|}~”””` - printable:键盘上的所有符号,值为:
digits + ascii_letters + punctuation + whitespace
5.5 random、string模块练习
- whitespace:ASCII码中所有的空白符号,值为:
练习一:在英文字母和数字中随机选择6个字符生成一个验证码。 ```python import random import string
data = string.ascii_letters + string.digits # 样本数据,包含所有英文字母和数字 verification_code = “” for i in range(6): verification_code += random.choice(data) print(verification_code)
- 练习二:让用户自己设定一个上下限,然后在上下限中随机生成一个整数,并让用户猜这个数字。
```python
# 导入模块
from random import randint
# 指定上下限,并生成随机数
lower_limit = eval(input("请输入下限:"))
upper_limit = eval(input("请输入上限:"))
random_num = randint(lower_limit, upper_limit)
# 猜测数字
while True:
my_num = eval(input(f"请在{lower_limit}到{upper_limit}中猜一个数字:"))
if my_num > upper_limit or my_num < lower_limit:
print("您猜测的范围超出当前提示的范围,请重新输入!")
elif my_num == random_num:
print("恭喜你猜对了。")
break
elif my_num < random_num:
print("很抱歉,猜小了。")
lower_limit = my_num
else:
print("很抱歉,猜大了。")
upper_limit = my_num
06. 经典算法——穷举法
6.1 穷举法的思想
- 穷举法是指按照需求将所有可能的情况都列出来,然后再根据实际需要对数据进行筛选,最后得到目标数据。
-
6.2 穷举法的经典例题
6.2.1 百马百担
问题描述:有一百匹马,要驮一百担货,大马驮3担,中马驮2担,两只小马驮1担。问有大,中,小马各几匹?
- 问题分析:
- 确定的量:马的总数和货的总数都是100。
- 先用极限法分析:
- 假设全用大马,则驮完100担货需要用34匹。(马的数量不到100)
- 假设全用中马,则驮完100担货需要用50匹。(马的数量不到100)
- 假设全用小马,则驮完100担货需要用200匹。(马的数量远超100)
- 发现极限法无法满足百马百担的要求,而且不知道什么情况才符合要求,因此根据穷举法的思路,可以把所有的组合都列出来,然后再按照要求排查。
代码实现:
for big in range(1, 34): # 34匹大马就可以搬完所有货物,由于别的马不能为0,因此大马肯定到不了34匹。
for middle in range(1, 50): # 50匹中就可以搬完所有货物,由于别的马不能为0,因此中马肯定到不了50匹。
for small in range(2, 100, 2): # 两匹小马可以驮一担货,因此单数的小马出现没有意义。
if 3 * big + 2 * middle + small // 2 == 100 and big + middle + small == 100: # 将百马百担的要求作为筛选条件。
print(f"大马:{big}只,中马:{middle}只,小马:{small}只")
6.2.2 百元百鸡
问题描述:
- 我国古代数学家张丘建在《算经》一书中提出的数学问题百元百鸡。
- 鸡翁一只5元,鸡母一只3元,鸡雏3只一元。
- 百元买百鸡,问鸡翁、鸡母、鸡雏各几何?
- 问题分析:解题思想与百马百担一致。
for chicken in range(1, 20):
for chicken_mother in range(1, 34):
for chicks in range(3, 100, 3):
if chicken + chicken_mother + chicks == 100 and 5 * chicken + 3 * chicken_mother + chicks // 3 == 100:
print(f"鸡翁:{chicken}只, 鸡母:{chicken_mother}只, 鸡雏:{chicks}只")