Python基础 - 控制结构
控制结构: 顺序, 分支, 循环, 理解了, 其实编程就入门一半了.
条件表达式
条件表达式的值只要不是:0 、 None、 False、 空列表、 空元组、 空集合、 空字典、 空字符串、 空range对象、或其他空迭代对象,Python解释器均认为与True等价
关系运算符
1 < 2 < 3 # 等价于 1 < 2 and 2 < 3
True
1 < 2 > 3
False
1 < 3 > 2
True
if a = 3: # 条件表达式中不允许使用赋值运算符
File "<ipython-input-4-0f1e37a77edb>", line 1
if a = 3: # 条件表达式中不允许使用赋值运算符
^
SyntaxError: invalid syntax
关系运算符具有惰性计算的特点,只计算必须计算的值,而不是计算关系表达式中的每个表达式
1 > 2 < sdkfjs # 后面的没有被运行哦, 程序没有报错呢
False
逻辑运算符
not and or 跟关系运算符类似,也具有短路(惰性)求值的特点,只计算必须计算表达式的值而非每个表达式的值
我总结如下:
exp1 and exp2:
exp1 为True, 返回exp2的值(不论真假) # True: 除了0, None, False, 空序列(list/tuple/set/dict/str/range)等,都是True
exp2 不为True, 直接返回exp1的值
exp1 or exp2:
exp1 为True, 返回exp2的值(不论真假) # True: 除了0, None, False, 空序列(list/tuple/set/dict/str/range)等,都是True
exp2 不为True, 直接返回exp1的值
not and or 跟关系运算符类似,也具有短路(惰性)求值的特点,只计算必须计算表达式的值而非每个表达式的值
我总结如下:
exp1 and exp2
exp1 为True, 返回exp2的值(不论真假) # True: 除了0, None, False, 空序列(list/tuple/set/dict/str/range)等,都是True
exp2 不为True, 直接返回exp1的值
exp1 or exp2
exp1 为True, 直接exp1的值
exp2 不为True, 返回exp2的值(不论真假)
在设计包含多个条件表达式时,若能大概预测不同条件失败的概率,并将多个条件根据and、or 逻辑运算符的短路求值来组织顺序,可以提高程序运行效率
3 and 5 # and: exp1 为真,返回exp2表达式的值,5
5
3 or 5 # or: exp1 为真, 直接返回exp1 的值 3
3
not 3 # 等价于 not True 即False
False
not 0 # 等价于 not False 即True
True
not None # 不是空,即True
True
# 用指定分隔符把多个字符串拼接成一个字符串,未指定则使用逗号
def str_join(char_list, sep=None):
return (sep or ',').join(char_list) # seq or ',' seq真,seq; seq不真,返回‘,’的值
s = ['c', 'h', 'e', 'n', 'j', 'i', 'e']
print(str_join(s))
print(str_join(s, ':'))
print(str_join(s, "@"))
c,h,e,n,j,i,e
c:h:e:n:j:i:e
c@h@e@n@j@i@e
选择结构
单分支选择 if
if 为真,则执行if里面的代码,否则则不执行,继续往下走
s = input("Input two numbers;")
a, b = map(int, s.split(",")) # 用逗号分割,并解包,map成数字
if a > b:
a, b = b, a # 解包,交换两个变量的值
print(a, b)
Input two numbers;8,1
1 8
if 3 > 2 : print('ok') # 可以写在一行,不过不建议
ok
双分支选择 if - else
# 鸡兔同笼问题
chicken_rabbit, sum_legs = map(int,input('Please enter the sum of chicken_rabbit and the sum of :').split(','))
rabbit = (sum_legs - chicken_rabbit * 2) / 2
if int(rabbit) == rabbit: # 兔子是整数
print("chicken: {0}, rabbit: {1}".format(int(chicken_rabbit - rabbit), int(rabbit)))
else:
print("Sory,the data you inpurt is wrong, i can not calculate the result exactly.")
Please enter the sum of chicken_rabbit and the sum of :77,100
chicken: 104, rabbit: -27
三元运算符: value if condtion else value2
a = 5
print(6) if a > 3 else print(5)
6
x = 6 if a > 10 else 9
x
9
多分支结构
if-elif-else
def func(score):
if score > 100 or score < 0:
return 'Wrong score must between 0 and 100'
elif score >= 90:
return 'A'
elif score >= 80:
return 'B'
elif score >= 70:
return 'C'
elif score >= 60:
return 'D'
else:
return 'E'
选择结构的嵌套
# 多层嵌套时候,一定要逻辑清晰, 名片管理系统,多练习练习
if exp1:
state1
if exp1.1:
state1.1
else:
state1.2
else:
if exp2:
state2.1
else:
state2.2
# 重构func 数据类型思维,编程思维
def func(score):
degree = 'DCBAE'
if score > 100 or score < 0:
return 'Wrong score must between 0 and 100'
else:
index = (score - 60) // 10 # (60, 0)(70, 1), (80, 2), (90, 3), (100,4), 恰好是作为索引
if index < 0:
return degree[-1] # 不及格,去最后一位索引值 E
else:
return degree[index]
循环结构
while 循环 与 for 循环
i = 0 # 循环增量,默认为0
s = 0
while i <= 100:
s = s + i
i = i + 1 # 增量,防止死循环,与 while条件关联
print("1+2+3+...100的和为:", s)
1+2+3+...100的和为: 5050
s = 0
for i in range(1, 101): # 遍历 1-100的序列
s += i
print("1+2+3+...100的和为:", s)
1+2+3+...100的和为: 5050
sum(range(101))
5050
a_list = ['a', 'b', 'cj', 123]
for i,v in enumerate(a_list):
print(i, v)
0 a
1 b
2 cj
3 123
for i in range(1, 101):
if i % 7 == 0 and i % 5 != 0: # 能被7整除,同时不能被5整除
print(i, end=' ')
7 14 21 28 42 49 56 63 77 84 91 98
打印 九九乘法表
for i in range(1, 10):
for j in range(1, i+1):
print("{0} * {1} = {2}".format(j, i, i * j), end='\t')
# print("%d * %d = %d" % (j, i, i * j), end='\t')
print()
1 * 1 = 1
1 * 2 = 2 2 * 2 = 4
1 * 3 = 3 2 * 3 = 6 3 * 3 = 9
1 * 4 = 4 2 * 4 = 8 3 * 4 = 12 4 * 4 = 16
1 * 5 = 5 2 * 5 = 10 3 * 5 = 15 4 * 5 = 20 5 * 5 = 25
1 * 6 = 6 2 * 6 = 12 3 * 6 = 18 4 * 6 = 24 5 * 6 = 30 6 * 6 = 36
1 * 7 = 7 2 * 7 = 14 3 * 7 = 21 4 * 7 = 28 5 * 7 = 35 6 * 7 = 42 7 * 7 = 49
1 * 8 = 8 2 * 8 = 16 3 * 8 = 24 4 * 8 = 32 5 * 8 = 40 6 * 8 = 48 7 * 8 = 56 8 * 8 = 64
1 * 9 = 9 2 * 9 = 18 3 * 9 = 27 4 * 9 = 36 5 * 9 = 45 6 * 9 = 54 7 * 9 = 63 8 * 9 = 72 9 * 9 = 81
while/for - break/continue - else
- break: 通常配合if使用,当条件满足break则跳出循环,else 不会被执行
- continue: 当continue,不会跳出循环,而是忽略continue后面的代码,开始下一次循环
- while/for - else: 循环正常走完,没有被break,则执行else,否则,不执行else
# 计算小于100的最大素数(约数 只有1 和它本身)
for i in range(100, 1, -1):
if i % 2 == 0:
continue # 偶数必然不会是素数,跳过,continue,进入下一次循环
# for j in range(3, i):
for j in range(3, int(i ** 0.5) + 1, 2): # 质数分布,根号n + 1
if i % j == 0:
break # 还有其他约数,则跳出 当前j 的 for,后面没有代码了,则继续回到i 的 for ,外层继续循环
else:
print(i) # 没有被break,正常走完,则执行else
# 结束外循环
break
97
举个栗子
- 输入若干成绩,求(输出)所有成绩平均分
- 每次输入一个成绩后,询问是否继续输入下一次成绩
- 回答yes就继续,no就停止输入
score = [] # 存放每个成绩
while True: # 成绩输入校验
try:
num = input("请输入一个成绩:")
score.append(float(num))
except:
print("您输入的不是合法成绩哦")
while True: # 第二次输入 yes/no 校验
cmd = input("继续输入吗? (yes/no)").lower() # 都转为小写判断,lower(),数字,特殊字符,不影响
# 输入判断
if cmd not in ('yes', 'no'):
print("只能输入 yes 或 no 哦")
else:
break # 输入正确,跳出输入校验
if cmd == 'no': # yes 不做处理,继续循环
break
if len(score) == 0:
print("您都没有输入成绩,就结束了,你好快哦")
else:
print("平均分是:", sum(score) / len(score))
请输入一个成绩:yyy
您输入的不是合法成绩哦
继续输入吗? (yes/no)no
您都没有输入成绩,就结束了,你好快哦
编写程序,判断今天是今年的第几天
import time
time.localtime()
time.struct_time(tm_year=2020, tm_mon=2, tm_mday=17, tm_hour=22, tm_min=16, tm_sec=31, tm_wday=0, tm_yday=48, tm_isdst=0)
import time
date = time.localtime()
year, month, day = date[0], date[1], date[2] # 获取当前的年月日
day_month = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 12]
# 判断是否为闰年(被400整除,或者,能别4整除 但 不能被100整除)
if year % 400 == 0 or (year % 4 == 0 and year % 100 != 0):
month[1] = 29
if month == 1:
print(day)
else:
sum(day_month[:month - 1]) + day # 求和前几个月的天数 + 当月天数, 10月27, 前9个月 + 当前日期
模拟决赛现场最终成绩的计算过程。
要求:
- 只要要有2位评委
- 分数必须在0-100之间
- 分数计算:去掉一个最高分、最低分,然后算平均分
# score = []
# while True:
# num = input("请输入评委的人数:")
# if not num.isdigit(): # 不是数字
# continue
# elif int(num) < 2:
# print("评委人数太少,必须多余两个人哦")
# continue
# else:
# break
# print(num)
while True:
try:
n = int(input("请输入评委的人数:"))
if n <= 2:
print("评委人数太少,必须要多余2人哦")
else:
break
except:
print("输入错误")
scores = []
# 获得正确的评委数量后,接下来逐一获取分数,必须在0-100之间
for i in range(n):
while True:
try:
score = input("请输入第 %d 个评委的分数:" % (i + 1))
score = float(score)
# 断言一下
assert 0 <= score <= 100
scores.append(score)
# 数据合法则跳出while,进入下一个评委
break
except:
print("分数错误")
score_h, score_l = max(scores), min(scores) # 最高分和最低分
scores.remove(score_h)
scores.remove(score_l)
# 计算剩余分数平均值,结果保留两位小数
final_score = round(sum(scores) / len(scores), 2)
# print(f"去掉一个最高分:{score_h} 去掉一个最低分:{score_l} 最后得分:{final_score} " % (score_h, score_l, final_score))
请输入评委的人数:3
请输入第 1 个评委的分数:9
请输入第 2 个评委的分数:8
请输入第 3 个评委的分数:8
# print(num)
while True:
try:
n = int(input("请输入评委的人数:"))
if n <= 2:
print("评委人数太少,必须要多余2人哦")
else:
break
except:
print("输入错误")
请输入评委的人数:xxx
输入错误
请输入评委的人数:3
输出由星号组成的菱形图案,并可以灵活控制图案的大小
def diamond_side(n):
for i in range(n):
print(('*' * i).center(n * 3, 'x')) # str.center()果然很强大
for j in range(n, 0, -1):
print(("*" * j).center(n * 3))
diamond_side(10)
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxx*xxxxxxxxxxxxxxx
xxxxxxxxxxxxxx**xxxxxxxxxxxxxx
xxxxxxxxxxxxx***xxxxxxxxxxxxxx
xxxxxxxxxxxxx****xxxxxxxxxxxxx
xxxxxxxxxxxx*****xxxxxxxxxxxxx
xxxxxxxxxxxx******xxxxxxxxxxxx
xxxxxxxxxxx*******xxxxxxxxxxxx
xxxxxxxxxxx********xxxxxxxxxxx
xxxxxxxxxx*********xxxxxxxxxxx
**********
*********
********
*******
******
*****
****
***
**
*
Docstring:
S.center(width[, fillchar]) -> str
Return S centered in a string of length width. Padding is
done using the specified fill character (default is a space)
编写程序,计算组合数C(n, i),即从N个元素中,任选i个,有多少种选法.
- 排列: 5 个里选择 2个,不考虑组合情况,则一个有 5 x 4 = 20种
- 排列: 5 * 4 * / (2 * 1) = 10 种
# 方案 直接用数学定义公式
def C1(n, i):
import math
return int(math.factorial(n) / math.factorial(i) / math.factorial(n-1))
小结
- 理解编程的控制流, 基本就入门一半了, 即理解代码执行的顺序, 重点是选择分支和循环
- 掌握 Python 中的 True 和 False 的对象, 而不是值哦, 万物皆对象
- 多用循环, 一共就两种, while 和 for, 其中 for 用得最多.