日了Dog的swap
2016-03-15 14:33
375 查看
来来来,先看几段程序:
(1)
a = 1
b = a
print a, b
a = a + 1
print a, b结果是:
1 1
2 1
(2)
a = [1]
b = a
print a, b
a[0] = a[0] + 1
print a, b
结果是:
[1] [1]
[2] [2]
(3)
1 2
1 2
(4)
def swap(a, b):
temp = a[0]
a[0] = b[0]
b[0] = temp
a = [1]
b = [2]
print a, b
swap(a, b)
print a, b
结果是:
[1] [2]
[2] [1]
(5)
def swap(a, b):
temp = a
a = b
b = temp
a = [1]
b = [2]
print a, b
swap(a, b)
print a, b
结果是:
[1] [2]
[1] [2]
我也想说.....一脸大写的懵逼..........
本来想像c++那样实现一下简单的swap,传个引用过去就好了,但是苦找找不到怎么在函数参数中传引用......
后来,满脑子问号的我看书寻求答案,踏破铁鞋无觅处的时候,我仿佛看到作者叼着一根烟,轻描淡写的说:其实,python里面全都是引用.....
再次一脸大写的懵逼的我继续看,发现,python是在声明第一个变量(引用)的时候开一块内存,如果声明第二个变量(引用)的时候,把第一个变量赋值过去,那两个变量(引用)就指向了同一块内存。
额......好吧给你们看书上的原话:
赋值语句建立对象引用值
变量名在首次赋值时会被创建
变量名在引用前必须先赋值
其实,会一点c的就发现,第一段程序有啥好看的,基本的语法嘛....
但是....如果这是C,我也会对第一段很不屑,但是一对比,不是说是对同一块内存进行操作吗?不是说都是引用吗?为什么a变了,b不变呢?
这就是很坑的一点,python在对于单个数值的时候,估计懒得检查内存了,反正一个数值占的内存小,多给你一块也无妨....(个人理解)
所以就每声明一个变量,分配一块内存,所以每个引用对应的是不同的内存。
但是对于数组(列表),连续的一块内存的时候,就会认真的多个引用对应一个内存了;
所以对于第二段程序,也就好理解了
接下来到了第三段,好吧,python的形参都是....用c++的话理解,浅拷贝,但是由于刚刚说过,所有声明的变量都是引用,引用是什么?内存地址呀,这就多出很多有意思的问题
第三段代码:
swap函数中的形参,就是a, b两个列表的地址,所以,即便是浅拷贝,我在swap函数中依然是对内存进行操作,所以交换得以成功
那么第四段呢?
我们和第五段合在一起,swap函数看起来都是相同的,第四段是传了两个数值的地址,由于浅拷贝的原因,你函数里对形参怎么折腾,跟我函数外实参没关系,该是啥还是啥
然后第五段改成两个列表的地址做形参,还是这样,对实参没影响;
但是,好吧,你再第三段和第五段呢?
对于列表来说,是不是也像c里面一样,列表名指向的的就是列表的首地址,两者等同呢?
虽然是这样, 两者都是指向同一块地址,但是a[0]这个操作就是在访问内存了
这么理解吧:
a 就是那个地址的数值
a[0]
就相当于c里面的 *(a+0), 访问了内存
所以...五段代码是解释清楚了,但是发现自己学一门语言就是做翻译一样,什么时候能真正掌握python的编程思想呢?
(1)
a = 1
b = a
print a, b
a = a + 1
print a, b结果是:
1 1
2 1
(2)
a = [1]
b = a
print a, b
a[0] = a[0] + 1
print a, b
结果是:
[1] [1]
[2] [2]
(3)
def swap(a, b): temp = a a = b b = temp a = 1 b = 2 print a, b swap (a, b) print a, b结果是:
1 2
1 2
(4)
def swap(a, b):
temp = a[0]
a[0] = b[0]
b[0] = temp
a = [1]
b = [2]
print a, b
swap(a, b)
print a, b
结果是:
[1] [2]
[2] [1]
(5)
def swap(a, b):
temp = a
a = b
b = temp
a = [1]
b = [2]
print a, b
swap(a, b)
print a, b
结果是:
[1] [2]
[1] [2]
我也想说.....一脸大写的懵逼..........
本来想像c++那样实现一下简单的swap,传个引用过去就好了,但是苦找找不到怎么在函数参数中传引用......
后来,满脑子问号的我看书寻求答案,踏破铁鞋无觅处的时候,我仿佛看到作者叼着一根烟,轻描淡写的说:其实,python里面全都是引用.....
再次一脸大写的懵逼的我继续看,发现,python是在声明第一个变量(引用)的时候开一块内存,如果声明第二个变量(引用)的时候,把第一个变量赋值过去,那两个变量(引用)就指向了同一块内存。
额......好吧给你们看书上的原话:
赋值语句建立对象引用值
变量名在首次赋值时会被创建
变量名在引用前必须先赋值
其实,会一点c的就发现,第一段程序有啥好看的,基本的语法嘛....
但是....如果这是C,我也会对第一段很不屑,但是一对比,不是说是对同一块内存进行操作吗?不是说都是引用吗?为什么a变了,b不变呢?
这就是很坑的一点,python在对于单个数值的时候,估计懒得检查内存了,反正一个数值占的内存小,多给你一块也无妨....(个人理解)
所以就每声明一个变量,分配一块内存,所以每个引用对应的是不同的内存。
但是对于数组(列表),连续的一块内存的时候,就会认真的多个引用对应一个内存了;
所以对于第二段程序,也就好理解了
接下来到了第三段,好吧,python的形参都是....用c++的话理解,浅拷贝,但是由于刚刚说过,所有声明的变量都是引用,引用是什么?内存地址呀,这就多出很多有意思的问题
第三段代码:
swap函数中的形参,就是a, b两个列表的地址,所以,即便是浅拷贝,我在swap函数中依然是对内存进行操作,所以交换得以成功
那么第四段呢?
我们和第五段合在一起,swap函数看起来都是相同的,第四段是传了两个数值的地址,由于浅拷贝的原因,你函数里对形参怎么折腾,跟我函数外实参没关系,该是啥还是啥
然后第五段改成两个列表的地址做形参,还是这样,对实参没影响;
但是,好吧,你再第三段和第五段呢?
对于列表来说,是不是也像c里面一样,列表名指向的的就是列表的首地址,两者等同呢?
虽然是这样, 两者都是指向同一块地址,但是a[0]这个操作就是在访问内存了
这么理解吧:
a 就是那个地址的数值
a[0]
就相当于c里面的 *(a+0), 访问了内存
所以...五段代码是解释清楚了,但是发现自己学一门语言就是做翻译一样,什么时候能真正掌握python的编程思想呢?
相关文章推荐
- Python动态类型的学习---引用的理解
- Python3写爬虫(四)多线程实现数据爬取
- 垃圾邮件过滤器 python简单实现
- 下载并遍历 names.txt 文件,输出长度最长的回文人名。
- install and upgrade scrapy
- Scrapy的架构介绍
- Centos6 编译安装Python
- 使用Python生成Excel格式的图片
- 让Python文件也可以当bat文件运行
- [Python]推算数独
- Python中zip()函数用法举例
- Python中map()函数浅析
- Python将excel导入到mysql中
- Python在CAM软件Genesis2000中的应用
- 使用Shiboken为C++和Qt库创建Python绑定
- FREEBASIC 编译可被python调用的dll函数示例
- Python 七步捉虫法