
一木.溪桥 在Logic Education跟Amy学Python
逻辑教育 :https://logicedu.ke.qq.com
12期:Python基础课
一木.溪桥学Python-08: for循环、function函数
日期:2020年12月日

学习目标:
- for循环
- function函数
学习内容:
for循环
for 循环表达式
虽然与 while 一样都是循环的关键字,但 for 循环通常用来遍历可迭代(iterable)的对象
for i in iterable:
pass
for i in '12':
print(type(i))
print(i)
'''
<class 'str'>
1
<class 'str'>
2
'''
for j in 12: # 报错:TypeError: 'int' object is not iterable
print(type(j))
print(j)
for i in range(4):
print(type(range))
print(i)
'''
<class 'type'>
0
<class 'type'>
1
<class 'type'>
2
<class 'type'>
3
'''
- tips:
- for … in …: 属于固定格式
- iterable 表示可迭代的对象
- i 是 变量名(可更改),代表可迭代对象里面的每个元素
range()
- range 是类
- 特点左闭右开,默认从0开始。
- 返回的是range()对象。
- range默认步长为1.
- 格式:range(start, stop, step)
print(type(range)) # <class 'type'>
print(range(10)) # range(0, 10)
print(list(range(10))) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
print(list(range(1, 10, 2))) # [1, 3, 5, 7, 9]
for 循环表达式练习
数字转为汉字大写输出
列表:
ch_num = [‘零’,‘壹’,‘贰’,‘叁’,‘肆’,‘伍’,‘陆’,‘柒’,‘捌’,‘玖’]
ch = [‘园’,‘拾’,‘佰’,‘仟’,‘萬’]
实现当输入数字时,将数字转为汉字大写输出。
# 列表:
# ch_num = ['零','壹','贰','叁','肆','伍','陆','柒','捌','玖']
# # ch = ['圆','拾','佰','仟','萬']
# 实现当输入数字时,将数字转为汉字大写输出。
ch_num = ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖']
ch = ['圆', '拾', '佰', '仟', '萬', '拾', '佰', '仟', '亿', '拾']
client_ipt = input("please input an int_num:") # 1234567
num_len = len(client_ipt)
for i in client_ipt:
num_len -= 1
print(f"{ch_num[int(i)]}{ch[num_len]}", end="") # 壹佰贰拾叁萬肆仟伍佰陆拾柒圆
print("整") # 整
99乘法表
for i in range(1, 10, 1):
for j in range(1, i+1, 1):
print(f"{j}*{i}={j*i}", end=" ")
print()
Run:
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
for 循环控制
-
break 与 continue 语句
在 while 循环中,拥有 break 与 continue 语句,那 for 循环中也有 break 与
continue 语句,并且作用一致。 -
问题:怎么跳出双层循环 ?
-
实现:
第一层循环建立标志
第二层循环改变标志,达到退出循环效果 -
break,跳出循环
for i in range(1, 10):
if i == 5:
break
print(i)
'''
run:
1
2
3
4
'''
- continue,跳过本次循环,断续下面的循环
for i in range(1, 7):
if i == 5:
continue
print(i)
'''
run:
1
2
3
4
6
'''
- 建立flag标志:当flag = True 时,退出外循环。
flag = False
for i in range(1, 10):
if flag:
break
for j in range(1, i+1):
if j == 3:
flag = True
print(f"{j}*{i}={j*i}", end=" ")
print()
'''
run:
1*1=1
1*2=2 2*2=4
1*3=3 2*3=6 3*3=9
'''
function函数
函数介绍:
函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段。
函数作用:
提高 应用的模块性 与 代码的复用性:
如 len() 、print()、 input()
if _ _ name_ _ == ‘_ _ main_ _’:
一个python文件通常有两种使用方法,第一是作为脚本直接执行,第二是 import 到其他的 python 脚本中被调用(模块重用)执行。因此if _ _ name _ _ == ‘_ _ main_ _’: 的作用就是控制这两种情况执行代码的过程,在if _ _ name _ _ == ’ _ _ main __ ': 下的代码只有在第一种情况下(即文件作为脚本直接执行)才会被执行,而 import 到其他脚本中是不会被执行的。
Python 解释器执行代码时,有一些内建、隐含的变量, __ name __ 就是其中之一,其意义是“模块名称”。如果该模块是被引用,那么 __ name __ 的值会是此模块的名称;如果该模块是直接被执行,那么 __ name __ 的值是 __ main __ 。
之所以常看见这样的写法,是因为该程序可能有“单独执行”(例如执行一些单元测试)与“被引用”两种情况,鉴于这两种情况中 _ _ name _ _ 的值是不同的:当一个模块被直接执行时,其 _ _ name _ _ 必然等于 _ _ main _ _ ;当一个模块被引用时,其 _ _ name _ _ 必然等于文件名(不含.py)。所以利用判断 _ _ name _ _ == ’ _ _ main _ _ '的真假就可以将这两种情况区分出来。
# const.py
PI = 3.14
def train():
print("PI:", PI)
train()
# area.py
from const import PI
def calc_round_area(radius):
return PI * (radius ** 2)
def calculate():
print("round area: ", calc_round_area(2))
calculate()
现在运行area.py文件,看结果:…
可以看见,const.py中的train()也被运行了,实际上我们是不希望它被运行,只是想把const.py中 PI 变量导入到 area.py。现在把 const.py 改一下:
PI = 3.14
def train():
print("PI:", PI)
if __name__ == "__main__":
train()
运行area.py文件发现没有执行const.py中train()。
自定义函数
- 定义规则:
函数代码块以 def 关键词开头 ,后接函数标识符名称和圆括号()
圆括号中间可以放入参数
函数内容以冒号起始,并且缩进。
def function_name(param):
print(‘func code’) - tips:
函数只有在调用时才会执行,通过 function_name(param) 进行调用
声明函数的那一行的上方需有两行的空行,不然报提示错误
函数的参数
- 形参与实参
- 可变类型参数与不可变类型参数
- 位置参数
- 关键字参数
- 默认值参数
- 可变长度参数
形参与实参:
- 形参 就是 函数定义中的 参数,没有实际的值,通过别人赋值后才有意义,相当于变量。
- 实参 就是 调用函数时传入的 参数,是一个实际存在的参数。
def function_name(param): 此处param为形参
print(’ func code ')
function_name(param) 此处param为实参
可变类型参数与不可变类型参数:
- 不可变类型参数在函数体内对变量重新赋值,相当于重新开辟了一块内存来保存值
- 可变类型参数在函数体内可以改变原有的值
位置参数:
- 位置参数也就是实参与形参顺序一一对应,而不论变量名
关键字参数:
- 以 形参 = 实参 形式指定,不论参数位置
默认值参数:
- 形参处进行赋值,所以当调用时不传该参数就默认使用形参处的值。当调用时传了该参数,则覆盖掉默认参数。
可变长度参数:
- *args 接收时会转为元组数据类型(打包为元组)
- tips:
- *args 可变长度的参数,可以传也可不传,并且长度不受限制,但会统一打包为元组。
- python3.0 之后,*args 参数后面只能跟关键字参数。
def test_one(*args):
print(args)
test_one()
test_one(1, 2, 3, 4)
run:
1 2 3 4
- **kwargs 接收时会转为字典数据类型(打包为字典)
- tips:
- **kwargs 可变长度的参数,可以传也可不传,并且长度不受限制,实参传需要传入键值对,然后形参会将它打包为字典。
def test_one(**kwargs):
print(kwargs)
test_one()
test_one(a=1, b=2, c=3, d=4)
run:
{}
{'a': 1, 'b': 2, 'c': 3, 'd': 4}
拆包
- 位置参数,形参 实参 个数一致,并且一一对应。
a, b, c = (1, 2, 3)
print(a, b, c, sep='\n')
run:
1
2
3
def test_one(a, b, c):
print(a, b, c)
tu = (1, 2, 3)
test_one(*tu)
run:
1 2 3
作业:
作业答案:
题1:
# 作业 1
# 1. 定义一个函数完成用户输入的三个数字的求和
# 以及在另一个函数求该和的平均值 ( 用到函数传参 , 函数返回值)
def sum_n(n):
sum_v = sum(n)
print(f"三数之和为:{sum_v}")
return sum_v
def f_avg(sum_a, len_b):
avg_n = sum_a / len_b
print("三数平均值为:{}".format(avg_n))
li = []
for i in range(1, 4):
while 1:
ipt = input(f"请输入第{i}个数字:")
if ipt.replace(".", '').isdigit():
li.append(float(ipt))
break
else:
print("", "输入有误,请重新输入1个数字!", "", sep="\n")
a = sum_n(li)
f_avg(a, len(li))
-
Run:1
请输入第1个数字:2
请输入第2个数字:3.6
请输入第3个数字:2.55
三数之和为:8.149999999999999
三数平均值为:2.7166666666666663 -
Run:2
请输入第1个数字:3
请输入第2个数字:d
输入有误,请重新输入1个数字!
请输入第2个数字:3.6
请输入第3个数字:3.2
三数之和为:9.8
三数平均值为:3.266666666666667
题2:
- 解1:
- 高级的写法不会呀,先来个最笨的吧,哈哈哈!!!
li = ["jack", ("tom", 23), "rose", (14, 55, 67)]
a, b, c, d = li
e, f = b
g, h, j = d
print(a, c, e, f, g, h, j, sep="\n")
- Run:
jack
rose
tom
23
14
55
67 - 解2:
- 想用*args拆包,没找到合适的判断语句,递归函数不太熟,先干半,留点养鱼吧!!!
def opt_tu(*args):
for args in args:
print(*args, sep="\n")
li = ["jack", ("tom", 23), "rose", (14, 55, 67)]
opt_tu(li)
-
Run:
jack
(‘tom’, 23)
rose
(14, 55, 67) -
解3:
-
网上搜索的一个,部分没看明白,先留下来!!!
def flattern(nested):
result = []
try:
try:
nested + ''
except TypeError:
pass
else:
raise TypeError
for sublist in nested:
for elememt in flattern(sublist):
yield elememt
except TypeError:
yield nested
def opt_tu(*args):
for args in args:
print("", "要求效果:", *args, sep="\n")
if __name__ == '__main__':
lst1 = ["jack", ("tom", 23), "rose", (14, 55, 67)]
print("原始列表:")
print(lst1)
print('嵌套遍历之后列表:')
lst2 = list(flattern(lst1))
print(lst2)
opt_tu(lst2)
- Run:
原始列表:
[‘jack’, (‘tom’, 23), ‘rose’, (14, 55, 67)]
嵌套遍历之后列表:
[‘jack’, ‘tom’, 23, ‘rose’, 14, 55, 67]
要求效果:
jack
tom
23
rose
14
55
67
题3:
- Amy的答案:
# 作业 1
# 生成了 N 个 1 ~ 1000 之间的随机整数 (N<=1000),N 是用户输入的,
# 对于其中重复的数字,只保留一个,把其余相同的数字去掉,然后再把这些数从小到大排序。
# ( 注意 : 此处需要使用 random 模块取随机整数。可课后拓展了解 random 模块具体方法 ; )
import random
n_nums = int(input("请输入:"))
# 初始化集合,用于去重
s = set()
for i in range(1, n_nums + 1):
# random.randint(1, 1000) 随机生成1个1~1000的整数 注意:范围是双闭合区间。
# random.randrange(1, 1001) 随机生成1个1~1000的整数 注意:范围是左闭右开的。
int_nums = random.randint(1, 1000)
# int_nums = random.randrange(1, 1001)
s.add(int_nums)
print(sorted(s, reverse=True)) # 返回列表并排序,reverse=True降序
Run:
请输入:5
[876, 789, 456, 419, 369]
题4:
- Amy的答案1:
# 作业 2
# 打印出所有的 " 水仙花数 " ,所谓 " 水仙花数 " 是指一个三位数,
# 其各位数字立方和等于该数本身。
# 例如: 153 是一个 " 水仙花数 " ,1^3 + 5^3+ 3^3 = 153
for i in range(100, 1000):
b = i // 100
s = i % 100 // 10
g = i % 10
if b**3 + s**3 + g**3 ==i:
print(f"水仙花数位:{i}")
-Run:
水仙花数位:153
水仙花数位:370
水仙花数位:371
水仙花数位:407
- Amy的答案2:
for i in range(100, 1000):
s = str(i)
num_sums = int(s[0])**3 + int(s[1])**3 + int(s[2])**3
if num_sums == i:
print(f"水仙花数位:{i}")
-Run:
水仙花数位:153
水仙花数位:370
水仙花数位:371
水仙花数位:407
End !
Best wishes for you!