内容概要:

一、递归

二、匿名函数

三、关于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. DDD分层架构之领域实体(基础篇)

    DDD分层架构之领域实体(基础篇) 上一篇,我介绍了自己在DDD分层架构方面的一些感想,本文开始介绍领域层的实体,代码主要参考自<领域驱动设计C#2008实现>,另外参考了网上找到的一些示 ...

  2. SQL Server之记录筛选(top、ties、offset)汇总

    一.TOP 筛选 如果有 ORDER BY 子句,TOP 筛选将根据排序的结果返回指定的行数.如果没有 ORDER BY 子句,TOP 筛选将按照行的物理顺序返回指定的行数. 1. 返回指定数目的行 ...

  3. [译]ava 设计模式之职责链

    (文章翻译自Java Design Pattern: Chain of Responsibility) 职责链模式的主要设计思想是为了构建一连串的处理单元,如果阈值满足的话那么这个单元就来处理这个请求 ...

  4. [译]ava 设计模式之享元

    (文章翻译自Java Design Pattern: Flyweight) 享元模式用于最小化内存开销.它做的就是使用其他相似的对象尽可能多的分享数据. 1.享元模式类图 2.享元模式Java代码 / ...

  5. Java集合之HashMap源码实现分析

    1.简介 通过上面的一篇随笔我们知道了HashSet的底层是采用Map实现的,那么Map是什么?它的底层又是如何实现的呢?这下我们来分析下源码,看看具体的结构与实现.Map 集合类用于存储元素对(称作 ...

  6. 【C#版本详情回顾】C#4.0主要功能列表

    诊断和性能 从 .NET Framework 4 开始,您可以获得每个应用程序域的处理器使用情况和内存使用情况估计值 通过托管承载 API.本机承载 API 以及 Windows 事件跟踪 (ETW) ...

  7. MVC为什么不再需要注册通配符(*.*)了?

    MVC为什么不再需要注册通配符(*.*)了? 文章内容 很多教程里都提到了,在部署MVC程序的时候要配置通配符映射(或者是*.mvc)到aspnet_ISPAI.dll上,在.NET4.0之前确实应该 ...

  8. Effective C++(14) 在资源管理类中小心copying行为

    问题聚焦:     上一条款所告诉我们的智能指针,只适合与在堆中的资源,而并非所有资源都是在堆中的.     这时候,我们可能需要建立自己的资源管理类,那么建立自己的资源管理类时,需要注意什么呢?. ...

  9. [置顶] c# 验证码生成

    今儿有一个任务是输出一串字符,要求用GDI画出于是: Bitmap bm = new Bitmap(200, 200);             Graphics g = Graphics.FromI ...

  10. Markdown 代码测试!

    # Mou ![Mou icon](http://mouapp.com/Mou_128.png) ## Overview **Mou**, the missing Markdown editor fo ...