<>循环结构

接上一篇。

<>for循环

通常用于可迭代对象的遍历。
注意,循环中的变量出来循环体外就会失效
for循环格式:
for 变量 in 可迭代对象: 循环体语句
例:
for x in (1,2,3,4,5): print(x)
对于可迭代对象
字符串,依次把字符串中字符输出。

字典
字典的键



字典的值

字典的键对

range
range(start,end,step)
start:起始值,不写默认0;end:结束值;step:步长,默认为1。

<>for语句的else

用法与while的else一样
for 变量 in 可迭代对象 循环体 else 语句块
下面整点活儿:
b=['name','age','type','number'] a=[] for i in range(4): an=input('请输入{0}:'.
format(b[i])) a.append(an) print('录入完成',end='! ') if an=='q': print('主动退出录入')
break else: c=dict(zip(b,a)) print('录入完成,录入结果为{0}'.format(c))
正常运行:会执行else的语句

break的情况下,没有执行else内的语句

<>break语句

可用于while和for循环,用来接收整个循环,当有嵌套循环时,break语句只能跳出最近的一层。

<>continue语句

只结束本次循环,整个循环继续。
continue后会提示不会运行它。

这里给个例子展示一下:注意输出的内容
x=0 while True: x+=1 print('第{0}轮'.format(x),end='\t') a=input() if a=='q':
print('break,circle is over',end='\t') break else: print('no break','\t') if a
== 'c': print('continue,just jump one circle') continue print('it`s wrong ,
continue isn`t work!') else: print('no break and no continue,a full circle')

<>嵌套循环练习

1.实现这样的阵列

我的写法:
for x in range(5): for i in range(5): if i<4: print(x,end='\t') else: print(x,
end='\n')
课上的写法
for x in range(5): for i in range(5): print(x,end='\t') print()
还是年轻了,没想到直接print()空输出来换行
2.打印下面的九九乘法表

我的写法
for x in range(1,10,1): for i in range(1,x+1,1): print(str(x),'*',str(i),'=',x*
i,end='\t') print()

课上讲的使用了.format来格式化输出
print("{0}*{1}={2}".format(x,i,x*i),end='\t')

3.用列表和字典存储下表信息,并打印出表中工资高于15000的数据

我写的:
l1={'name':'高小一','年龄':'18','薪资':30000,'城市':'北京'} l2={'name':'高小二','年龄':'19',
'薪资':20000,'城市':'上海'} l3={'name':'高小五','年龄':'20','薪资':10000,'城市':'深圳'} a=[l1,l2,
l3] for x in a: if x.get('薪资')>=15000: print(x)

这次思路一样了,不写课上的代码了。

<>循环代码的优化

1.尽量减少循环内部不必要的计算;
2.嵌套循环中见谅减少内层的计算,将计算向外提;
3.局部变量查询的较快,尽量使用局部变量。

<>使用zip()进行并行迭代

其实有其他方法实现,这里只是说zip可以实现这种效果

<>推导式创建序列

<>列表推导式

生成列表对象
[表达式 for item in 可迭代对象] a=[x**2 for x in range(1,5,1)] print(a)


[表达式 for item in 可迭代对象 if 条件判断] a=[x**2 for x in range(1,10,1) if x%2==0] print
(a)

更复杂的甚至可以写:
a=[(x,y)for x in range(3) for y in range(3)] print(a)

整活
a=['{0}*{1}={2}'.format(x,y,x*y) for x in range(1,10,1) for y in range(1,x+1,1)
] count=0 for i in range(0,9,1): for b in range(0,i+1,1): print(a[count],end=' '
) count+=1 print() print('乘法表')

<>字典推导式

生成字典对象
{key_expression : value_expression for 表达式 in 可迭代对象} a1=['name','age','type']
a2=['temmie',23,'dog'] a={a1[i]:a2[i] for i in range(2)} print(a)

课上给了一个更加有用的例子:统计一句话中各种字母的个数:
text='i am temmie!temmie!!temmie!!!' a={c:text.count(c) for c in text} print(a)
因为字典的键不能重复,所以本应该出现所有字符的,但每一个字符只出现了一次。

<>集合推导式
{expression for 表达式 in 可迭代对象}
跟字典的类似,这里就不演示了。

<>生成器推导式(生成元组)

注意:生成器运行一次只能用一次。生成器是一个可迭代的对象,使用的时候按照可迭代对象一样使用即可。
gnt=(x for x in range(1,100) if x%9==0) for x in gnt: print(x,end=' ')

<>练习:绘制不同颜色同心圆

先补充两个小海龟的语法:
1.可以赋值变量来简化输入:t=turtle.Pen(),这样后面调用时可以直接写t.circle来简化输入代码。
2.turtle.done()可以让绘制后的窗口不关闭(以前我的绘图截屏都是靠开debug来截图的,淦!)
3.turtle.speed()来设置绘制速度
import turtle as t t.width('5') t.speed(0) co=('red','orange','yellow','green',
'cyan','blue','purple') for i in range(1,7,1): t.color(co[i]) t.penup() t.goto(0
,-50*i) t.pendown() t.circle(50*i) t.done()

<>练习:绘制棋盘
import turtle as t t.width('5') t.speed(0) for f in range(0,2,1): for i in
range(0,5,1): if f==0: t.penup() t.goto(-100,50*i) t.pendown() t.goto(100,50*i)
else: t.penup() t.goto(50*(i-2),0) t.pendown() t.goto(50*(i-2),200) t.done()

<>函数

函数是可重复用的程序代码块。是对代码的封装,增加了函数调用、传递参数、返回计算结果等内容。
查询函数文档可以使用:
help(函数名.__doc__)

<>python中的函数分类

1.内置函数:我们可以直接使用的都是内置函数
2.标准库函数:我们通过import导入库,然后使用的函数。
3.第三方库函数:在社区中下载安装,使用import导入的第三方函数。
4.用户自定义函数:我们自己创建的函数。

<>定义函数的方法:
def 函数名([参数列表]): '''文档字符串(说明注释)''' 函数体/若干语句
多个参数时用 **,**隔开。无参数也要保留函数。
例:
创建
def temmie(n): for i in range(1,n+1,1): print('temmie','!'*i)
调用
temmie(5)

<>形参与实参

形参是函数定义时使用,是局部变量,超出函数部分将无效。形参不需要指定类型,实参与形参应是一一对应的。
def 函数名(形参1,形参2…)
实参是在调用函数时,传递的参数称为实参。
函数名(实参1,实参2…)

<>函数的返回值

return语句可以写或不写,不写默认返回None。
使用时格式:return 表达式
return后的语句不会执行。
对象=函数名(实参),这样就把返回值给了对象。
函数也是一个对象,你也可以不传给其他变量,直接作为一个对象使用。
对于要返回多个值时,可以利用列表、字典等来将多个数据返回。

<>全局变量与局部变量(变量的作用域)

变量起作用的模块被称为变量的作用域。不同作用域内各同名变量互不影响。
全局变量::
 1.在函数和类定义之外声明的变量。作用域为定义的模块,从定义位置开始知道模块结束;
 2.全局变量降低了函数通用性和可读性,应尽量避免全局变量的使用;
 3.全局变量一般做常量使用;
 4.函数内要改变全局变量的值,需要使用global声明一下;
局部变量::
 1.在函数体中(包含形参)声明的变量;
 2.局部变量的引用比全局量快,优先考虑使用;
 3.如果局部变量和全局变量同名,这在函数内隐藏全局变量,只使用同名的局部变量。如果想用要用global声明一下再用。
输出全局、局部变量
使用下面的语句
print(locals()) print(globals()) a=100 b=200 def temmie_num(): a=1000 print(a)
global b b=400 print('这是局部变量',locals()) print('这是全局变量',globals()) temmie_num()

<>参数的传递

函数的参数传递本质上就是:从实参到形参的赋值操作。
1.对于可变对象
字典、列表、集合、自定义的对象等,传递操作实际上是传递的内容地址。是对同一个对象进行操作。
2.对于不可变对象
数字、字符串、元组、function 等,传递操作是创建了一个新的对象。
a=100#数字,不可变对象 b=[200]#列表,可变对象 print(type(a),type(b)) print('a与b的地址',id(a),id(b
)) def temmie(m,n): print('m与n的地址',m,id(m),n,id(n),'传递进来的地址') m=m*2 n.append(20)
print('m与n的地址',m,id(m),n,id(n)) temmie(a,b)#a是不可变对象,b是可变对象 print(a,b)

但我在自己尝试的时候有一点疑问,如果对列表操作换成n=n*2的话,它的地址会改变。

<>浅拷贝(copy)与深拷贝(deepcopy)

浅拷贝:不拷贝子对象的内容,只是拷贝子对象的引用。
深拷贝:会连子对象的内存也全部拷贝一份,对子对象的修改不会影响源对象。
使用时需要导入copy模块
我们用代码试验一下:
import copy a=[10,20,[30,40]] b=[50,60,[70,80]] a_c=copy.copy(a) b_c=copy.
deepcopy(b) a_c[2][1]=100 print(a,'\n',a_c) b_c[2][1]=100 print(b,'\n',b_c)
print('a的元素地址:',a[0],':',id(a[0]),a[1],':',id(a[1]),a[2][0],':',id(a[2][0]),a[2]
[1],':',id(a[2][1])) print('a_c的元素地址:',a_c[0],':',id(a_c[0]),a_c[1],':',id(a_c[1
]),a_c[2][0],':',id(a_c[2][0]),a_c[2][1],':',id(a_c[2][1])) print('b的元素地址:',b[0]
,':',id(b[0]),b[1],':',id(b[1]),b[2][0],':',id(b[2][0]),b[2][1],':',id(b[2][1]))
print('b_C的元素地址:',b_c[0],':',id(b_c[0]),b_c[1],':',id(b_c[1]),b_c[2][0],':',id(
b_c[2][0]),b_c[2][1],':',id(b_c[2][1]))
结果:

下面我用图文表示一下我的理解:

也就是说,如果列表a有一个小本本,这个小本本记着它包含多少元素,每个元素在哪的话,浅拷贝只是把列表a的本本复制了一个一样的,而列表a中包含的列表b的小本本还是用的之前的;深拷贝则把所有本本都复制了一个。

<>参数的几种类型

<>位置参数

函数调用时,实参默认按照位置顺序传递,需要个数和形参匹配。按位置传递的参数,称为:位置参数

<>默认值参数

例如:def fuction1(a,b,c=1,d=2)
这面c和d就是默认值参数,如果调用函数时不给出则默认使用这些值,给出则使用输入的值。默认值参数必须放到最后面

<>命名参数

如:def fuction1(a,b,c)
在调用时写 fuction(c=1,b=2,a=10)则与写fuction(10,2,1)效果相同,但这样写可以乱序输入。

<>可变参数

* *param,将多个参数收集到一个元组对象中。
* **param,将多个采纳数收集到一个字典对象中。 def temmie(a,b,*c): print(a,b,c) def temmie01(a,b,
**c): print(a,b,c) temmie(1,2,3,4,5,6) temmie01(1,2,name='temmie',age=23)
#注意这里面字典的表述方式!!

<>强制命名参数

对于上面可变参数,如果列在前面,会出现不知道从哪到哪是属于这个可变参数的值,所以如果函数定义时写成:
*def fuction01(a,b,c)
这种形式的话,调用应写作:
fuction01(1,2,3,4,b=1,c=2)
这样将名字写入,其他没有指定的就都是*a的内容。

<>lambda表达式和匿名函数

lambda表达式可以用来声明匿名函数,是一种简单的,在同一行中定义函数的方法。
lambda只允许包含一个表达式,不能包含复杂语句,该表达式的就是那结果就是函数的返回值。
lambda arg1,arg2...:<表达式>
arg1,arg2…相当于函数的参数,<表达式>相当于函数体。

<>eval函数

将字符串 str 当成有效的表达式来求值并返回计算结果。
eval(source[, globals[, locals]]) -> value
整个活吧:
while True: message=input('temmie say:') if message=='q': print('tteemmiiee
say:see ya!!!!',end='') break else: print('tteemmiiee alsooo say:',end='') eval(
message)

<>递归函数

递归函数指的是:自己调用自己的函数,在函数体内部直接或间接的自己调用自己。
每个递归函数必须包含下面两部分:1.终止条件:表示递归什么时候结束,一般用于返回值,不再调用自己;2.递归步骤:把第n步的值和第n-1步相关联。
递归函数会大量占用资源,小心使用。
例子:计算阶乘
def fuction01(n): if n==1: return 1 else: return n*fuction01(n-1) a=fuction01(5
) print(a)

<>嵌套函数(内部函数)

在函数内部定义的函数
就是这样:
def outer_fuction(): 代码块 def inner_fuction(): 代码块 inner_fuction()#外函数调用内函数
outer_fuction()#使用外部函数
注意,内部函数只能由这个外部函数使用,其他位置无法调用该内部函数。
作用:封装:外部无法访问嵌套函数。2.避免函数内部代码重复。3.闭包(暂时没讲)

技术
下载桌面版
GitHub
百度网盘(提取码:draw)
Gitee
云服务器优惠
阿里云优惠券
腾讯云优惠券
华为云优惠券
站点信息
问题反馈
邮箱:ixiaoyang8@qq.com
QQ群:766591547
关注微信