内容概要:

一、递归

二、匿名函数

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

一、递归

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

递归特性:

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

示列1:求10!的值。

 #方法一递归实现
#/usr/bin/env python
# -*- coding:utf-8 -*-
#Author:W-D
def sumn(n):
if n<=2:#递归结束条件
return n
else:
return (n * sumn(n-1))#调用函数本身
print(sumn(10))
结果:
3628800 方法二:for循环实现
a=1
for i in range(1,11):
a=a*i
print(a)
结果:
3628800

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

 #/usr/bin/env python
# -*- coding:utf-8 -*-
#Author:W-D
def feola(n1,n2):
n3=n1+n2
if n1>500:#结束条件为数大于500
return
print("{}".format(n1))#打印值
feola(n2,n3)#自身调用
feola(0,1)
结果:
0
1
1
2
3
5
8
13
21
34
55
89
144
233
377
 
 
二、匿名函数lambda

匿名函数,顾名思义就是不需要显示的定义函数名的函数,但是在语法上受限于一个表达式。

语法:

 函数名=lambda 参数:代码

示列:

 #/usr/bin/env python
# -*- coding:utf-8 -*-
#Author:W-D
f=lambda x,y:x+y#匿名函数表达式
print(f(3,2))#调用
结果:
5 #换个姿势用普通方式定义
def my_add(x,y):
return x+y
print(my_add(3,2))#调用
结果:
5
三、关于python中的深浅拷贝与赋值

说明:

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

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

如:

 #/usr/bin/env python
# -*- coding:utf-8 -*-
#Author:W-D
import copy
a=1
b=copy.copy(a)
print(a,b)
结果:
1 1

浅copy

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

如:

 #/usr/bin/env python
# -*- coding:utf-8 -*-
#Author:W-D
import copy
a=1
b=copy.deepcopy(a)
print(a,b)
结果:
1 1

深copy

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

如:

 #/usr/bin/env python
# -*- coding:utf-8 -*-
#Author:W-D
a="WD"
print(id(a))
结果:
7578824

区别比较:

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

1.数字类型

 >>> a=1
>>> b=a#赋值
>>> id(a),id(b)
(1855455696, 1855455696)#内存地址一样
>>> a=2#改变初始值
>>> id(a),id(b)
(1855455728, 1855455696)
>>> a,b
(2, 1)#不会影响赋值以后的值
>>> c=3
>>> import copy
>>> d=copy.copy(c)#浅拷贝
>>> id(c),id(d)
(1855455760, 1855455760)#内存地址一样
>>> c=6
>>> id(c),id(d)
(1855455856, 1855455760)#同赋值
>>> c,d
(6, 3)
>>> d=copy.deepcopy(c)#深度拷贝
>>> id(c),id(d)
(1855455856, 1855455856)#内存地址一样
>>> c=5
>>> id(c),id(d)
(1855455824, 1855455856)#修改不影响初始值
>>>

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

2.字符串

 >>> a="name"
>>> b=a
>>> id(a),id(b)
(3447696, 3447696)#内存地址相同
>>> a="WD"
>>> id(a),id(b)
(8140144, 3447696)#同数字,改变a,只改变了a的地址,b没有影响,内存地址不变
>>> del a,b
>>> a="name"
>>> import copy
>>> b=copy.copy(a)
>>> id(a),id(b)
(3447696, 3447696)
>>> a="alex"
>>> id(a),id(b)
(8140032, 3447696)#同上
>>> del a,b
>>> a="jack"
>>> b=copy.deepcopy(a)#同上
>>> id(a),id(b)
(8140032, 8140032)
>>> a="flask"
>>> id(a),id(b)
(8140200, 8140032)

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

3.列表

 >>> a=[1,2,3,[4,5,6]]
>>> b=a
>>> id(a),id(b)
(10695880, 10695880)#内存地址相同
>>> a=['a','b','c']
>>> id(a),id(b)
(10695944, 10695880)#改变a整个列表,结果和数字、字符串一样
>>> a,b
(['a', 'b', 'c'], [1, 2, 3, [4, 5, 6]])
>>> del a,b
>>> a=[1,2,3,[7,8,9]]
>>> b=a
>>> id(a),id(b)
(10696520, 10696520)
>>> a[0]="N"#改变列表中的元素的值
>>> id(a),id(b)
(10696520, 10696520)#内存地址没有改变
>>> a,b
(['N', 2, 3, [7, 8, 9]], ['N', 2, 3, [7, 8, 9]])#影响了b的值
>>> a[3][1]="A"
>>> id(a),id(b)
(10696520, 10696520)
>>> a,b
(['N', 2, 3, [7, 'A', 9]], ['N', 2, 3, [7, 'A', 9]])

赋值操作

结果分析:列表的赋值操作如果对于改变整个列表而言,结果和字符串、数字类型相同,但是如果修改列表中某个元素,在示列中修改了a列表中元素,导致了b列表也改变了。这是因为在python中,列表下标存储的是数值的内存地址,而不是值本身,当我们修改整个列表的时候改变了最外层内存地址,这时候情况也相当于数字和字符串。当我们修改了下标的值的时候,其内存地址也发生了变化,而最外层的内存地址没有发生变化,列表a和b同时指向同一个内存地址,此时修改a列表中元素的值,也相当于修改了b列表,这中情况可以理解为linux中的别名。

 >>> import copy
>>> a=[1,2,3,[4,5,6]]
>>> b=copy.copy(a)#浅拷贝
>>> id(a),id(b)
(17628744, 10894536)#外层地址不通
>>> a[0]="A"
>>> a
['A', 2, 3, [4, 5, 6]]
>>> b
[1, 2, 3, [4, 5, 6]]
>>> id(a[3]),id(b[3])
(17671944, 17671944)#第二层地址相同
>>> a[3]="name"#改变整个第二层值
>>> a
['A', 2, 3, 'name']
>>> b
[1, 2, 3, [4, 5, 6]]
>>> id(a[3]),id(b[3])
(6200208, 17671944)#只影响a
>>> del a,b
>>> a=[1,2,3,[4,5,6]]
>>> b=copy.copy(a)
>>> id(a[3][0]),id(b[3][0])
(1520960048, 1520960048)
>>> a[3][0]="WD"
>>> id(a[3][0]),id(b[3][0])#修改第二层中的列表,可见两个内存地址都变了,也就是说b中的值也变了
(10888392, 10888392)
>>> a
[1, 2, 3, ['WD', 5, 6]]
>>> b
[1, 2, 3, ['WD', 5, 6]]
>>>

浅copy

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

 >>> import copy
>>> a=[1,2,3,[4,5,6]]
>>> b=copy.deepcopy(a)#深copy
>>> id(a),id(b)
(11337288, 11380360)#外层内存地址不同
>>> id(a[3][0]),id(b[3][0])
(1520960048, 1520960048)#内存元素地址相同
>>> a[3][0]="WD"#改变a
>>> a
[1, 2, 3, ['WD', 5, 6]]
>>> b
[1, 2, 3, [4, 5, 6]]
>>> id(a[3][0]),id(b[3][0])#不想影响b
(10954040, 1520960048)

深copy(deepcopy)

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

 >>> a=[1,2,3,[4,5,6]]
>>> b=a.copy()
>>> id(a),id(b)
(17249480, 17249608)
>>> a[3][0]="WD"
>>> id(a[3][0]),id(b[3][0])
(17245552, 17245552)
>>> a
[1, 2, 3, ['WD', 5, 6]]
>>> b
[1, 2, 3, ['WD', 5, 6]]

list中的copy方法

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

4.字典

 >>> a={'name':'wd','age':22,'msg':{'sex':'man','like':'python'}}
>>> b=a
>>> id(a),id(b)
(6668040, 6668040)
>>> id(a['msg']['sex']),id(b['msg']['sex'])
(7087752, 7087752)
>>> a['msg']['sex']='boy'
>>> id(a['msg']['sex']),id(b['msg']['sex'])
(7087976, 7087976)
>>> a
{'msg': {'sex': 'boy', 'like': 'python'}, 'age': 22, 'name': 'wd'}
>>> b
{'msg': {'sex': 'boy', 'like': 'python'}, 'age': 22, 'name': 'wd'}
>>> a['msg']="alex"
>>> id(a['msg']),id(b['msg'])#和列表不同修改内层整个变量,也会影响b
(7087920, 7087920)
>>> a
{'msg': 'alex', 'age': 22, 'name': 'wd'}
>>> b
{'msg': 'alex', 'age': 22, 'name': 'wd'}

赋值操作

结果分析:字典的赋值操作和列表一样,无论修改外层元素还是内层元素,结果都一样,等同于别名。

 >>> a={'k1':1,'k2':2,'k3':{'name':'wd'}}
>>> import copy
>>> b=copy.copy(a)#浅copy
>>> id(a),id(b)
(6799112, 7224648)
>>> id(a['k2']),id(b['k2']#第二层内存地址相同
(1509229040, 1509229040)
>>> id(a['k1']),id(b['k1'])
(1509229008, 1509229008)
>>> a['k1']='AA'#修改第二层整个变量只会影响a
>>> id(a['k1']),id(b['k1'])
(7218656, 1509229008)
>>> a
{'k1': 'AA', 'k3': {'name': 'wd'}, 'k2': 2}
>>> b
{'k1': 1, 'k3': {'name': 'wd'}, 'k2': 2}
>>> id(a['k3']['name']),id(b['k3']['name'])#第二层内存地址相同
(7218600, 7218600)
>>> a['k3']['name']='alex'
>>> id(a['k3']['name']),id(b['k3']['name'])#修改第二层中的变量的值影响b
(7219272, 7219272)
>>> a
{'k1': 'AA', 'k3': {'name': 'alex'}, 'k2': 2}
>>> b
{'k1': 1, 'k3': {'name': 'alex'}, 'k2': 2}
>>>

浅copy

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

 >>> a={'m1':1,'m2':2,'m3':{'name':'WD'}}
>>> import copy
>>> b=copy.deepcopy(a)#深copy
>>> id(a),id(b)
(10534664, 17276488)#外层内存地址不同
>>> id(a['m1']),id(b['m1'])
(1528037840, 1528037840)#内层地址相同
>>> a['m1']='AA'
>>> id(a['m1']),id(b['m1'])
(17318552, 1528037840)
>>> a
{'m3': {'name': 'WD'}, 'm1': 'AA', 'm2': 2}
>>> b
{'m3': {'name': 'WD'}, 'm1': 1, 'm2': 2}
>>> a['m3']['name']='alex'
>>> a
{'m3': {'name': 'alex'}, 'm1': 'AA', 'm2': 2}#改变a互不影响
>>> b
{'m3': {'name': 'WD'}, 'm1': 1, 'm2': 2}
>>>

深copy(deepcopy)

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

 >>> a={'m1':1,'m2':2,'m3':{'name':'WD'}}
>>> b=a.copy()
>>> id(a),id(b)
(6668040, 16882632)
>>> a['m1']="AA"
>>> a
{'m1': 'AA', 'm3': {'name': 'WD'}, 'm2': 2}
>>> b
{'m1': 1, 'm3': {'name': 'WD'}, 'm2': 2}
>>> a['m3']['name']="alex"
>>> a
{'m1': 'AA', 'm3': {'name': 'alex'}, 'm2': 2}
>>> b
{'m1': 1, 'm3': {'name': 'alex'}, 'm2': 2}
>>>

字典的copy方法

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

总结:

1.对于数字、字符串这些“简单的”数据类型,赋值、深copy、浅copy都一样,并且随意修改其中一个变量,并不影响另一个变量的值。

2.对于列表、字典这些“复杂”的数据类型,赋值操作相当于给变量取了别名,修改变量里的内容,都会改变,修改整个变量则无影响;浅copy和copy方法结果相同,对外层进行拷贝,修改第一层的元素相互不会影响,当列表或者字典中嵌套了列表或字典,修改嵌套的列表或者字典(也可以叫做第二层中的元素)导致两个变量都会改变;深copy相当于复制两份互不影响的数据。

使用建议:

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

python基础4的更多相关文章

  1. python之最强王者(2)——python基础语法

    背景介绍:由于本人一直做java开发,也是从txt开始写hello,world,使用javac命令编译,一直到使用myeclipse,其中的道理和辛酸都懂(请容许我擦干眼角的泪水),所以对于pytho ...

  2. Python开发【第二篇】:Python基础知识

    Python基础知识 一.初识基本数据类型 类型: int(整型) 在32位机器上,整数的位数为32位,取值范围为-2**31-2**31-1,即-2147483648-2147483647 在64位 ...

  3. Python小白的发展之路之Python基础(一)

    Python基础部分1: 1.Python简介 2.Python 2 or 3,两者的主要区别 3.Python解释器 4.安装Python 5.第一个Python程序 Hello World 6.P ...

  4. Python之路3【第一篇】Python基础

    本节内容 Python简介 Python安装 第一个Python程序 编程语言的分类 Python简介 1.Python的由来 python的创始人为吉多·范罗苏姆(Guido van Rossum) ...

  5. 进击的Python【第三章】:Python基础(三)

    Python基础(三) 本章内容 集合的概念与操作 文件的操作 函数的特点与用法 参数与局部变量 return返回值的概念 递归的基本含义 函数式编程介绍 高阶函数的概念 一.集合的概念与操作 集合( ...

  6. 进击的Python【第二章】:Python基础(二)

    Python基础(二) 本章内容 数据类型 数据运算 列表与元组的基本操作 字典的基本操作 字符编码与转码 模块初探 练习:购物车程序 一.数据类型 Python有五个标准的数据类型: Numbers ...

  7. Python之路【第一篇】python基础

    一.python开发 1.开发: 1)高级语言:python .Java .PHP. C#  Go ruby  c++  ===>字节码 2)低级语言:c .汇编 2.语言之间的对比: 1)py ...

  8. python基础之day1

    Python 简介 Python是著名的“龟叔”Guido van Rossum在1989年圣诞节期间,为了打发无聊的圣诞节而编写的一个编程语言. Python为我们提供了非常完善的基础代码库,覆盖了 ...

  9. python基础之文件读写

    python基础之文件读写 本节内容 os模块中文件以及目录的一些方法 文件的操作 目录的操作 1.os模块中文件以及目录的一些方法 python操作文件以及目录可以使用os模块的一些方法如下: 得到 ...

  10. python基础之编码问题

    python基础之编码问题 本节内容 字符串编码问题由来 字符串编码解决方案 1.字符串编码问题由来 由于字符串编码是从ascii--->unicode--->utf-8(utf-16和u ...

随机推荐

  1. C#用WebClient下载File时操作超时的问题

    原文:C#用WebClient下载File时操作超时的问题 今天很SB,被这个问题卡住了.那段代码也是网上找的.结果发现只能下载一个文件,第二次下载的时候就会出现“操作超时”的问题. 这个是原代码: ...

  2. ASP.NET vNext 在 Mac OS

    让 ASP.NET vNext 在 Mac OS 中飞呀飞...   写在前面 阅读目录: 娓娓道来 Install ASP.NET vNext Command Line Tools 安装 Homeb ...

  3. innerText与innerHTML的区别

    innerText与innerHTML的区别:1.innerText将所有文本内容作为普通的文本2.innerHTML会识别文本内容中是否含有html标签,它能够把html标签的效果显示出来3.inn ...

  4. JS定时跳转URL并输出剩余秒数

    1. [代码][JavaScript]代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 <scrip ...

  5. Javascript多线程引擎(三)

    Javascript多线程引擎(三) 完成对ECMAScript-262 3rd规范的阅读后, 列出了如下的限制条件 1. 去除正则表达式( 语法识别先不编写) 2. 去除对Function Decl ...

  6. RequireJS 入门指南

    RequireJS 入门指南 http://requirejs.org/ 简介如今最常用的JavaScript库之一是RequireJS.最近我参与的每个项目,都用到了RequireJS,或者是我向它 ...

  7. Web Api的安全性

    Web Api的安全性 系列导航地址http://www.cnblogs.com/fzrain/p/3490137.html 前言 这一篇文章我们主要来探讨一下Web Api的安全性,到目前为止所有的 ...

  8. How To Configure Logging And Log Rotation In Apache On An Ubuntu VPS

    Introduction The Apache web server can be configured to give the server administrator important info ...

  9. nginx 重定向到index.php

    location /keywords {                index index.php;                try_files $uri $uri/ /keywords/i ...

  10. PureMVC(JS版)源码解析

    PureMVC(JS版)源码解析:总结   PureMVC源码中设计到的11个类已经全部解析完了,回首想想,花了一周的时间做的这点事情还是挺值得的,自己的文字组织表达能力和对pureMVC的理解也在写 ...