作为一个python初学者,今天被一个python列表和词典引用的问题折磨了很久,但其实了解了缘由也很简单,记录在此备忘。

首先背书python中的引用对象问题:

1. python不允许程序员选择采用传值还是传引用。Python参数传递采用的肯定是“传对象引用”的方式。实际上,这种方式相当于传值和传引用的一种综合。如果函数收到的是一个可变对象(比如字典或者列表)的引用,就能修改对象的原始值——相当于通过“传引用”来传递对象。如果函数收到的是一个不可变对象(比如数字、字符或者元组)的引用,就不能直接修改原始对象——相当于通过“传值'来传递对象。

2. 当人们复制列表或字典时,就复制了对象列表的引用同,如果改变引用的值,则修改了原始的参数。

3. 为了简化内存管理,Python通过引用计数机制实现自动垃圾回收功能,Python中的每个对象都有一个引用计数,用来计数该对象在不同场所分别被引用了多少次。每当引用一次Python对象,相应的引用计数就增1,每当消毁一次Python对象,则相应的引用就减1,只有当引用计数为零时,才真正从内存中删除Python对象。

 

列表引用

首先看2个示例:

 1 def add_list(p):
 2     p = p + [1]
 3 p1 = [1,2,3]
 4 add_list(p1)
 5 print p1
 6 >>> [1, 2, 3]
 7
 8 def add_list(p):
 9     p += [1]
10 p2 = [1,2,3]
11 proc2(p2)
12 print p2
13 >>>[1, 2, 3, 1]

这主要是由于“=”操作符会新建一个新的变量保存赋值结果,然后再把引用名指向“=”左边,即修改了原来的p引用,使p成为指向新赋值变量的引用。而+=不会,直接修改了原来p引用的内容,事实上+=和=在python内部使用了不同的实现函数。

 

词典引用

1 a = []
2 b = {'num':0, 'sqrt':0}
3 resurse = [1,2,3]
4 for i in resurse:
5   b['num'] = i
6   b['sqrt'] = i * i
7   a.append(b)
8 print a
9 >>> [{'num': 3, 'sqrt': 9}, {'num': 3, 'sqrt': 9}, {'num': 3, 'sqrt': 9}]

但我们实际想要的结果是这样的:

>>> [{'num': 1, 'sqrt': 1}, {'num': 2, 'sqrt': 4}, {'num': 3, 'sqrt': 9}]

这是由于a中的元素就是b的引用。可以修改为:

1 a = []
2 resurse = [1,2,3]
3 for i in resurse:
4   a.append({"num": i, "sqrt": i * i})

实例

接下来可以看看折磨我半天的一个实例:

定义一个家族谱词典:value为key的parent. 要写一个函数,输入人名,给出这个人的所有祖先名字。

开始的做法:

 1 ada_family = { 'Judith Blunt-Lytton': ['Anne Isabella Blunt', 'Wilfrid Scawen Blunt'],
 2               'Ada King-Milbanke': ['Ralph King-Milbanke', 'Fanny Heriot'],
 3               'Ralph King-Milbanke': ['Augusta Ada King', 'William King-Noel'],
 4               'Anne Isabella Blunt': ['Augusta Ada King', 'William King-Noel'],
 5               'Byron King-Noel': ['Augusta Ada King', 'William King-Noel'],
 6               'Augusta Ada King': ['Anne Isabella Milbanke', 'George Gordon Byron'],
 7               'George Gordon Byron': ['Catherine Gordon', 'Captain John Byron'],
 8               'John Byron': ['Vice-Admiral John Byron', 'Sophia Trevannion'] }
 9
10
11 def ancestors(genealogy, person):
12     if person in genealogy:
13         parents = genealogy[person]
14         result = parents
15         for parent in parents:
16             result += ancestors(genealogy, parent)
17         return result
18     return []
19 print ancestors2(ada_family, 'Judith Blunt-Lytton')
20 print ada_family
21
22 #>>> ['Anne Isabella Blunt', 'Wilfrid Scawen Blunt', 'Augusta Ada King',
23 #    'William King-Noel', 'Anne Isabella Milbanke', 'George Gordon Byron',
24 #    'Catherine Gordon', 'Captain John Byron', 'Catherine Gordon',
25 #    'Captain John Byron', 'Anne Isabella Milbanke', 'George Gordon Byron',
26 #    'Catherine Gordon', 'Captain John Byron', 'Catherine Gordon',
27 #    'Captain John Byron', 'Catherine Gordon', 'Captain John Byron',
28 #    'Catherine Gordon', 'Captain John Byron']
29 #
30 #>>> {'Ralph King-Milbanke': ['Augusta Ada King', 'William King-Noel'],
31 #    'Ada King-Milbanke': ['Ralph King-Milbanke', 'Fanny Heriot'],
32 #    'Anne Isabella Blunt': ['Augusta Ada King', 'William King-Noel', 'Anne Isabella Milbanke', 'George Gordon Byron', 'Catherine Gordon', 'Captain John Byron', 'Catherine Gordon', 'Captain John Byron'],
33 #    'Augusta Ada King': ['Anne Isabella Milbanke', 'George Gordon Byron', 'Catherine Gordon', 'Captain John Byron', 'Catherine Gordon', 'Captain John Byron'],
34 #    'Judith Blunt-Lytton': ['Anne Isabella Blunt', 'Wilfrid Scawen Blunt', 'Augusta Ada King', 'William King-Noel', 'Anne Isabella Milbanke', 'George Gordon Byron', 'Catherine Gordon', 'Captain John Byron', 'Catherine Gordon', 'Captain John Byron', 'Anne Isabella Milbanke', 'George Gordon Byron', 'Catherine Gordon', 'Captain John Byron', 'Catherine Gordon', 'Captain John Byron', 'Catherine Gordon', 'Captain John Byron', 'Catherine Gordon', 'Captain John Byron'],
35 #    'Byron King-Noel': ['Augusta Ada King', 'William King-Noel'],
36 #    'George Gordon Byron': ['Catherine Gordon', 'Captain John Byron'],
37 #    'John Byron': ['Vice-Admiral John Byron', 'Sophia Trevannion']}

这并不是我想要的结果,开始检查了好久都不明所以,直到我突然想起来打印词典ada_family,才发现词典已经不是原来的值了,这时,我才反应过来是引用的原因。由于我们使用的result实际就是词典中的value列表的引用,改动了result,就也改动了ada_family词典,从而导致结果不正确(有很多重复项)。

修改为如下写法即可。

 1 def ancestors(genealogy, person):
 2     if person in genealogy:
 3         parents = genealogy[person]
 4         result = parents
 5         for parent in parents:
 6             result = result + ancestors2(genealogy, parent)
 7         return result
 8     return []
 9
10 #>>> ['Anne Isabella Blunt', 'Wilfrid Scawen Blunt', 'Augusta Ada King',
11 #    'William King-Noel', 'Anne Isabella Milbanke', 'George Gordon Byron',
12 #    'Catherine Gordon', 'Captain John Byron']
13 #
14 #>>> {'Ralph King-Milbanke': ['Augusta Ada King', 'William King-Noel'],
15 #    'Ada King-Milbanke': ['Ralph King-Milbanke', 'Fanny Heriot'],
16 #    'Anne Isabella Blunt': ['Augusta Ada King', 'William King-Noel'],
17 #    'Augusta Ada King': ['Anne Isabella Milbanke', 'George Gordon Byron'],
18 #    'Judith Blunt-Lytton': ['Anne Isabella Blunt', 'Wilfrid Scawen Blunt'],
19 #    'Byron King-Noel': ['Augusta Ada King', 'William King-Noel'],
20 #    'George Gordon Byron': ['Catherine Gordon', 'Captain John Byron'],
21 #    'John Byron': ['Vice-Admiral John Byron', 'Sophia Trevannion']}

此时就不会修改原词典内容,得到的也是正确结果。

当然,我们也可以简单的使用以下方法实现,就避免了引用带来的麻烦:

1 def ancestors(genealogy, person):
2     if person in genealogy:
3         parents = genealogy[person]
4         return parents + ancestors(genealogy,parents[0]) + ancestors(genealogy,parents[1])
5     return []

这里再备忘一些关于列表和词典的操作:

列表  list[]

赋值 list1[3:4]=[a,b]

len(list)长度

del list 删除对象

列表对象支持的方法:

append(x) 尾部追加 单个对象x,使用多个对象会引起异常。

count(x) 返回对象x在list中出现的次数

extend(L) 将列表L中的项添加到表中

index(x) 返回匹配对象x第一个表项的索引,无匹配时产生异常

insert(i,x) 在索引‘i’的元素钱插入对象x

pop(x) 删除列表中索引x的表项,并返回同该表项的值,无参数删除最后

remove(x) 删除表匹配对象x的第一个元素,无匹配时异常

reverse() 颠倒列表元素的顺序

sort() 对列表排序

此外可简单使用+实现列表连接:[3,4] + [[1,2],5,6] --> [3,4,[1,2],5,6]

删除列表中的重复项:M = list(set(L)),python的set和其他语言类似, 是一个无序不重复元素集

词典 dictionary{name:value,...}

+++字典的方法

has_keys(x) 若字典中有x返回true

keys() 返回键的列表

values() 返回值的列表

dict.items() 返回tuples的列表。每个tuple有字典的dict的键和相应的值组成

clear() 删除词典的所有条目

copy() 返回字典的高层结构的拷贝,但不复制嵌入结构,而复制那些结构的引用。

update(x) 用字典x中的键/值对更新字典的内容。

get(x[,y]) 返回键x。若未找到返回None

内置对象类型转换

str(x) 将对象x翻译为字符串

list(x) 将对象序列x作为列表返回。例如‘hello’返回['h','e','l','l','o'],将tuple转换为列表

tuple(x) 将对象序列x作为tuple返回

int(x) 将字符串和数字转换为整数,对浮点进行舍位而非舍入

long(x) 将字符串和数字转换为长整形

float(x) 将str和num转换为浮点对象

complex(x,y) 将x做实部,y做虚部创建复数

hex(x) 将整数或长整数转换为十六进制字符串

oct(x) 将整数或长整数转换为八进制字符串

ord(x) 返回字符x的ASCII值

chr(x) 返回ASCII码x代表的字符

min(x[,...]) 返回序列中最小的元素

max(x[,...]) 返回序列中最大的元素

参考

http://opengit.org/open/?f=python_note

http://blog.csdn.net/wayne92/article/details/1133465

http://hliang.sinaapp.com/?p=233

转载于:https://www.cnblogs.com/yuyan/archive/2012/04/21/2461673.html

关于Python中的引用相关推荐

  1. python中的引用、浅拷贝和深拷贝

    在python中,有一句话:"一切皆为对象,一切皆为对象的引用",所以 只要记住这句话就很容易清楚python中的引用.浅拷贝和深拷贝了. 1. 引用 python中的引用是经常使 ...

  2. c++中的引用和python中的引用_对比 C++ 和 Python,谈谈指针与引用

    作者 | 樱雨楼 引言 指针(Pointer)是 C.C++ 以及 Java.Go 等语言的一个非常核心且重要的概念,而引用(Reference)是在指针的基础上构建出的一个同样重要的概念. 指针对于 ...

  3. 非常易于理解‘类'与'对象’ 间 属性 引用关系,暨《Python 中的引用和类属性的初步理解》读后感...

    关键字:名称,名称空间,引用,指针,指针类型的指针(即指向指针的指针) 我读完后的理解总结: 1. 我们知道,python中的变量的赋值操作,变量其实就是一个名称name,赋值就是将name引用到一个 ...

  4. python中的引用_Python中的引用

    我有一个多播网络,需要不断地向所有其他用户发送数据.我不想让程序员不断地改变数据包的发送方式.正因为如此,我试图找出如何引用Python中的任何对象或变量(我是Python新手),这样用户就可以修改它 ...

  5. c++中的引用和python中的引用_【总结】C++、C#、Java、Javascript、Python中引用的区别...

    首先分两大阵营:C++中引用是一块阵营, C#.Java.Javascript.Python中引用是另一块阵营. 之所以这样分是因为同一阵营中引用使用方法基本一样. C++引用本质是个常量指针,而其他 ...

  6. python中的引用怎么理解_python 引用和对象理解

    今天浏览博客的时候看到这么一句话: python中变量名和对象是分离的:最开始的时候是看到这句话的时候没有反应过来.决定具体搞清楚一下python中变量与对象之间的细节.(其实我感觉应该说 引用和对象 ...

  7. python中的引用怎么理解_Python函数通过引用调用

    基本上有三种'函数调用':通过价值 通过引用传递 通过对象引用传递 Python是一种PASS-BY-OBJECT-REFERENCE编程语言. 首先,重要的是要理解一个变量,变量(对象)的值是两个独 ...

  8. python学习—python中的引用本质

    python引用概念 python中可以使用 id函数查看引用的是否为同一个内存空间,如果返回值相同,说明引用相同.在python中,值是靠引用来传递的. python中所有的变量都是在堆中开辟内存, ...

  9. 【Python】Python中的引用和赋值

    本文转自:http://my.oschina.net/leejun2005/blog/145911 在 python 中赋值语句总是建立对象的引用值,而不是复制对象.因此,python 变量更像是指针 ...

最新文章

  1. php-5.2.3.tar.bz2.gz 的解压方法
  2. html5 拖拽的简要介绍
  3. 图解ecshop之批量上传与批量处理
  4. AndroidStudio创建jinLibs文件夹
  5. 运维编排场景系列----给实例加到SLS机器组
  6. 哥哥被我打哭了的飞鸽传书
  7. 解决xampp启动mysql失败
  8. In_interrupt( ) 和In_irq( )【转】
  9. Java转型,多态和契约设计
  10. 保障健康睡眠的几种食疗法
  11. 易语言解析html实例,易语言解析JSON教程
  12. 第三届长安杯检材一复盘
  13. 流氓的Lenovo Drivers Management联想驱动管理程序
  14. python+pygame安装教程win8
  15. java如何开发国内手机短信验证码接口
  16. 为了中国---我国民用客机深度报道(第三部分下)
  17. 2021计算机excel,excel2021版本
  18. 空间实景三维激光点云数据处理服务来了!
  19. RE合同记账会计凭证
  20. 系统自带功能之视频压缩

热门文章

  1. vivo手机删除自带程序方法
  2. php框架 猪婆,猪婆塘_三湖文学社_新高淳论坛 - Powered by Discuz!
  3. 详解脑的功能区域分布以及布罗德曼分区系统
  4. Python操作表格
  5. 揭开物联网的神秘面纱--物联网小灯
  6. 我的世界服务器兑换系统怎么做,Minecraft我的世界村民交易方法及兑换表格
  7. 出色不如走运全文第二部分
  8. 汉字 字库压缩ttf
  9. 搜狗都上市了,王小川还是单身,难道要找AI当女朋友?
  10. 微信小程序利用canvas绘制一个动画百分比圆圈