python基础4之递归、lambda、深浅copy

python基础4之递归、lambda、深浅copy,第1张

概述内容概要:一、递归二、匿名函数三、关于python中的深浅拷贝与赋值 一、递归递归就是函数本身调用自己,直到满足指定条件之后一层层退出函数递归特性:必须有一个明确的结束条件每次进入更深一层递归时,问题规模相比上次递归都应有所减少递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出)示列1:求10!的值。1 #方法一递归实现2 #/usr/bin/env python3 # -*- coding:utf-8 -*-4 #Author:W-D5 def sumn(n):6 if n<=2:#递归结束条件7 return n8 else:9 return (n * sumn(n-1))#调用函数本身10 print(sumn(10))11 结果:12 36288001314 方法二:for循环实现15 a=116 for i in range(1,11):17 a=a*i18 print(a)19 结果:20 3628800示列二:使用递归的方式来生成斐波那契数列(斐波那契数列就是前面给两个数相加得到后面一个数,依次往后)1 #/usr/bin/env python2 # -*- coding:utf-8 -*-3 #Author:W-D4 def feola(n1,n2):5 n3=n1+n26 if n1>500:#结束条件为数大于5007 return8 print("{}".format(n1))#打印值9 feola(n2,n3)#自身调用10 feola(0,1)11 结果:12 013 114 115 216 317 518 819 1320 2121 3422 5523 8924 14425 23326 377View Code  二、匿名函数lambda 匿名函数,顾名思义就是不需要显示的定义函数名的函数,但是在语法上受限于一个表达式。语法:1 函数名=lambda 参数:代码示列:1 #/usr/bin/env python2 # -*- coding:utf-8 -*-3 #Author:W-D4 f=lambda x,y:x+y#匿名函数表达式5 print(f(3,2))#调用6 结果:7 589 #换个姿势用普通方式定义10 def my_add(x,y):11 return x+y12 print(my_add(3,2))#调用13 结果:14 5 三、关于python中的深浅拷贝与赋值说明:1.赋值:将一个变量的值赋给另一个变量(例如,name1=“WD” name2=name1,将name1的值赋给name2)2.浅拷贝:copy模块中的copy方法如:1 #/usr/bin/env python2 # -*- coding:utf-8 -*-3 #Author:W-D4 import copy5 a=16 b=copy.copy(a)7 print(a,b)8 结果:9 1 1浅copy3.深度拷贝:copy模块中的deepcopy方法如:1 #/usr/bin/env python2 # -*- coding:utf-8 -*-3 #Author:W-D4 import copy5 a=16 b=copy.deepcopy(a)7 print(a,b)8 结果:9 1 1深copy4.查看变量使用的内存地址使用id的方法如:1 #/usr/bin/env python2 # -*- coding:utf-8 -*-3 #Author:W-D4 a="WD"5 print(id(a))6 结果:7 7578824View Code 区别比较:在python中不同的数据类型的赋值、深浅拷贝结果不通,为此需要区别对待,同时为了方便验证,我们在交互模式下测试,测试环境python3.5.2.1.数字类型1 >>> a=12 >>> b=a#赋值3 >>> id(a),id(b)4 (1855455696, 1855455696)#内存地址一样5 >>> a=2#改变初始值6 >>> id(a),id(b)7 (1855455728, 1855455696)8 >>> a,b9 (2, 1)#不会影响赋值以后的值10 >>> c=311 >>> import copy12 >>> d=copy.copy(c)#浅拷贝13 >>> id(c),id(d)14 (1855455760, 1855455760)#内存地址一样15 >>> c=616 >>> id(c),id(d)17 (1855455856, 1855455760)#同赋值18 >>> c,d19 (6, 3)20 >>> d=copy.deepcopy(c)#深度拷贝21 >>> id(c),id(d)22 (1855455856, 1855455856)#内存地址一样23 >>> c=524 >>> id(c),id(d)25 (1855455824, 1855455856)#修改不影响初始值26 >>>View Code结果分析:对于数字类型,无论是赋值还是深浅拷贝,赋值或拷贝以后内存地址都一样,修改拷贝前的值,会重新分配一个新的内存地址,并不影响拷贝后的值。2.字符串1 >>> a="name"2 >>> b=a3 >>> id(a),id(b)4 (3447696, 3447696)#内存地址相同5 >>> a="WD"6 >>> id(a),id(b)7 (8140144, 3447696)#同数字,改变a,只改变了a的地址,b没有影响,内存地址不变8 >>> del a,b9 >>> a="name"10 >>> import copy11 >>> b=copy.copy(a)12 >>> id(a),id(b)13 (3447696, 3447696)14 >>> a="alex"15 >>> id(a),id(b)16 (8140032, 3447696)#同上17 >>> del a,b18 >>> a="jack"19 >>> b=copy.deepcopy(a)#同上20 >>> id(a),id(b)21 (8140032, 8140032)22 >>> a="flask"23 >>> id(a),id(b)24 (8140200, 8140032)View Code结果分析:字符串类型和数字类型结果一样,改变a的值,会重新分配内存地址,并不影响b的值3.列表1 >>> a=[1,2,3,[4,5,6]]2 >>> b=a3 >>> id(a),id(b)4 (10695880, 10695880)#内存地址相同5 >>> a=['a','b','c']6 >>> id(a),id(b)7 (10695944, 10695880)#改变a整个列表,结果和数字、字符串一样8 >>> a,b9 (['a', 'b', 'c'], [1, 2, 3, [4, 5, 6]])10 >>> del a,b11 >>> a=[1,2,3,[7,8,9]]12 >>> b=a13 >>> id(a),id(b)14 (10696520, 10696520)15 >>> a[0]="N"#改变列表中的元素的值16 >>> id(a),id(b)17 (10696520, 10696520)#内存地址没有改变18 >>> a,b19 (['N', 2, 3, [7, 8, 9]], ['N', 2, 3, [7, 8, 9]])#影响了b的值20 >>> a[3][1]="A"21 >>> id(a),id(b)22 (10696520, 10696520)23 >>> a,b24 (['N', 2, 3, [7, 'A', 9]], ['N', 2, 3, [7, 'A', 9]])赋值 *** 作结果分析:列表的赋值 *** 作如果对于改变整个列表而言,结果和字符串、数字类型相同,但是如果修改列表中某个元素,在示列中修改了a列表中元素,导致了b列表也改变了。这是因为在python中,列表下标存储的是数值的内存地址,而不是值本身,当我们修改整个列表的时候改变了最外层内存地址,这时候情况也相当于数字和字符串。当我们修改了下标的值的时候,其内存地址也发生了变化,而最外层的内存地址没有发生变化,列表a和b同时指向同一个内存地址,此时修改a列表中元素的值,也相当于修改了b列表,这中情况可以理解为linux中的别名。1 >>> import copy2 >>> a=[1,2,3,[4,5,6]]3 >>> b=copy.copy(a)#浅拷贝4 >>> id(a),id(b)5 (17628744, 10894536)#外层地址不通6 >>> a[0]="A"7 >>> a8 ['A', 2, 3, [4, 5, 6]]9 >>> b10 [1, 2, 3, [4, 5, 6]]11 >>> id(a[3]),id(b[3])12 (17671944, 17671944)#第二层地址相同13 >>> a[3]="name"#改变整个第二层值14 >>> a15 ['A', 2, 3, 'name']16 >>> b17 [1, 2, 3, [4, 5, 6]]18 >>> id(a[3]),id(b[3])19 (6200208, 17671944)#只影响a20 >>> del a,b21 >>> a=[1,2,3,[4,5,6]]22 >>> b=copy.copy(a)23 >>> id(a[3][0]),id(b[3][0])24 (1520960048, 1520960048)25 >>> a[3][0]="WD"26 >>> id(a[3][0]),id(b[3][0])#修改第二层中的列表,可见两个内存地址都变了,也就是说b中的值也变了27 (10888392, 10888392)28

内容概要:

一、递归

二、匿名函数

三、关于python中的深浅拷贝与赋值

<table border="0"><tr>
<td><span >一、递归</td>
</tr></table>

递归就是函数本身调用自己,直到满足指定条件之后一层层退出函数

递归特性:

必须有一个明确的结束条件每次进入更深一层递归时,问题规模相比上次递归都应有所减少递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出)

示列1:求10!的值。

n<=2: (n * sumn(n-1)) (sumn(10 3628800 a=1 i range(1,11 a=a* 3628800

示列二:使用递归的方式来生成斐波那契数列(斐波那契数列就是前面给两个数相加得到后面一个数,依次往后)

n3=n1+ n1>500: (.format(n1)) feola(n2,n3) feola(0,1 1 1 2 3 5 8 13 21 34 55 89 144 233 377 匿名函数,顾名思义就是不需要显示的定义函数名的函数,但是在语法上受限于一个表达式。

语法:

函数名= 参数:代码

示列:

f= x,y:x+y (f(3,2)) 5 x+ (my_add(3,2)) 5

<table border="0">

<tr>
<td><span >三、关于python中的深浅拷贝与赋值</td>
</tr></table>

说明:

1.赋值:将一个变量的值赋给另一个变量(例如,name1=“WD” name2=name1,将name1的值赋给name2)

2.浅拷贝:copy模块中的copy方法

如:

a=1 b= 1 1

3.深度拷贝:copy模块中的deepcopy方法

如:

a=1 b= 1 1

4.查看变量使用的内存地址使用ID的方法

如:

a= 7578824

区别比较:

在python中不同的数据类型的赋值、深浅拷贝结果不通,为此需要区别对待,同时为了方便验证,我们在交互模式下测试,测试环境python3.5.2.

1.数字类型

>>> a=1 >>> b=a >>> (1855455696,1855455696) >>> a=2 >>> (1855455728,1855455696 >>> (2,1) >>> c=3 >>> >>> d=copy.copy(c) >>> (1855455760,1855455760) >>> c=6 >>> (1855455856,1855455760) >>> (6,3 >>> d=copy.deepcopy(c) >>> (1855455856,1855455856) >>> c=5 >>> (1855455824,1855455856) >>>

结果分析:对于数字类型,无论是赋值还是深浅拷贝,赋值或拷贝以后内存地址都一样,修改拷贝前的值,会重新分配一个新的内存地址,并不影响拷贝后的值。

2.字符串

>>> a= >>> b= >>> (3447696,3447696) >>> a= >>> (8140144,3447696) >>> >>> a= >>> >>> b= >>> (3447696,3447696 >>> a= >>> (8140032,3447696) >>> >>> a= >>> b=copy.deepcopy(a) >>> (8140032,8140032 >>> a= >>> (8140200,8140032)

结果分析:字符串类型和数字类型结果一样,改变a的值,会重新分配内存地址,并不影响b的值

3.列表

>>> a=[1,2,3,[4,5,6 >>> b= >>> (10695880,10695880) >>> a=[,, >>> (10695944,10695880) >>> ([,],[1,6 >>> >>> a=[1,[7,8,9 >>> b= >>> (10696520,10696520 >>> a[0]= >>> (10696520,10696520) >>> ([,9]],[,9]]) >>> a[3][1]= >>> (10696520,10696520 >>> ([,,9]])

结果分析:列表的赋值 *** 作如果对于改变整个列表而言,结果和字符串、数字类型相同,但是如果修改列表中某个元素,在示列中修改了a列表中元素,导致了b列表也改变了。

>>> >>> a=[1,6 >>> b=copy.copy(a) >>> (17628744,10894536) >>> a[0]= >>> [,6 >>> [1,6 >>> ID(a[3]),ID(b[3 (17671944,17671944) >>> a[3]= >>> [, >>> [1,6 >>> ID(a[3]),ID(b[3 (6200208,17671944) >>> >>> a=[1,6 >>> b= >>> ID(a[3][0]),ID(b[3 (1520960048,1520960048 >>> a[3][0]= >>> ID(a[3][0]),ID(b[3][0]) (10888392,10888392 >>> [1,[,6 >>> [1,6 >>>

结果分析:浅copy,只对外层内存地址做拷贝,拷贝之后的两个列表内存地址不同,两个变量的第二层内存地址相同,修改整个第二层对拷贝后的变量无影响,但修改第二层中的元素的值,会影响拷贝后的值,从内存地址上看就很清晰了。

>>> >>> a=[1,6 >>> b=copy.deepcopy(a) >>> (11337288,11380360) >>> ID(a[3][0]),ID(b[3 (1520960048,1520960048) >>> a[3][0]= >>> [1,6 >>> [1,6 >>> ID(a[3][0]),ID(b[3][0]) (10954040,1520960048)

结果分析:深copy,只对外层内存地址做拷贝,内层地址相同,但是不通的是改变内层中元素的值,并不影响拷贝后的变量,相当于两份独立的数据。

>>> a=[1,6 >>> b= >>> (17249480,17249608 >>> a[3][0]= >>> ID(a[3][0]),ID(b[3 (17245552,17245552 >>> [1,6 >>> [1,6]]

结果分析:从结果上看,List中的列表方法也是浅copy。

4.字典

>>> a={:,:22,:{:,: >>> b= >>> (6668040,6668040 >>> ID(a[][]),ID(b[][ (7087752,7087752 >>> a[][]= >>> ID(a[][]),ID(b[][ (7087976,7087976 >>> {: {: ,: },: 22,: >>> {: {: ,: >>> a[]= >>> ID(a[]),ID(b[]) (7087920,7087920 >>> {: ,: >>> {: ,: }

结果分析:字典的赋值 *** 作和列表一样,无论修改外层元素还是内层元素,

>>> a={:1,:2,:{: >>> >>> b=copy.copy(a) >>> (6799112,7224648 >>> ID(a[]),ID(b[] (1509229040,1509229040 >>> ID(a[]),ID(b[ (1509229008,1509229008 >>> a[]= >>> ID(a[]),ID(b[ (7218656,1509229008 >>> {: ,: {: },: 2 >>> {: 1,: 2 >>> ID(a[][]),ID(b[][]) (7218600,7218600 >>> a[][]= >>> ID(a[][]),ID(b[][]) (7219272,7219272 >>> {: ,: {: },: 2 >>> {: 1,: 2 >>>

结果分析:字典的浅拷贝和列表一样,使用copy方法拷贝字典后,a,b字典外层内存地址不同,第二层内存地址相同,修改a字典中整个第二层变量不会影响b字典,修改a字典中第二层中的元素的时候,会影响b字典。

>>> a={:1,:2,:{: >>> >>> b=copy.deepcopy(a) >>> (10534664,17276488) >>> ID(a[]),ID(b[ (1528037840,1528037840) >>> a[]= >>> ID(a[]),ID(b[ (17318552,1528037840 >>> {: {: },: ,: 2 >>> {: {: },: 1,: 2 >>> a[][]= >>> {: {: },: 2} >>> {: {: },: 2 >>>

结果分析:字典的深copy和列表相同,相当于两份独立的数据。

>>> a={:1,:{: >>> b= >>> >>> a[]= >>> {: ,: {: },: 2 >>> {: 1,: 2 >>> a[][]= >>> {: ,: {: },: 2 >>> {: 1,: 2 >>>

结果分析:字典的copy方法也相当于浅copy。

1.对于数字、字符串类型可以随心所遇,对于字典、列表如果想得到两份不同的数据,建议使用copy.deepcopy的方法。

总结

以上是内存溢出为你收集整理的python基础4之递归、lambda、深浅copy全部内容,希望文章能够帮你解决python基础4之递归、lambda、深浅copy所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/1207914.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-04
下一篇 2022-06-04

发表评论

登录后才能评论

评论列表(0条)