关闭

python 字典学习2

标签: Python
150人阅读 评论(0) 收藏 举报
分类:
copy


>>> a = 5
>>> b = a
>>> b 
5
对象有类型,变量无类型,变量其实是一个标签。


>>> id(a)
139774080
>>> id(b)
138774080
果然,并没有两个5,就一个,只不过是贴了两张标签而已。


>>> ad = {"name":"qiwsir", "lang":"python"}
>>> bd = ad
>>> bd
{'lang':'python','name':'qiwsir'}
>>> id(ad)
3072239652L
>>> id(bd)
3072239652L
是的,验证了。的确是一个对象贴了两个标签。这是用赋值的方式,实现的所谓“


假装拷贝”。


>>> cd = ad.copy()
>>> cd
{'lang':'python','name':'qiwsir'}
>>> id(cd)
3072239788L
果然不同 ,这次得到的cd是跟原来的ad不同的,它在内存中另辟了一个空间。


>>> cd["name"] = "itdiffer.com"
>>> cd
{'lang': 'python', 'name': 'itdiffer.com'}
>>> ad
{'lang': 'python', 'name': 'qiwsir'}
变量是对象的标签,对象有类型二变量无类型。


>>> bd
{'lang': 'python'.'name': 'qiwsir'}
>>> bd["name"] = "laoqi"
>>> ad
{'lang': 'python'.'name': 'laoqi'}
>>> bd
{'lang': 'python'.'name': 'laoqi'}
修改了bd所对应的“对象”,结果发现ad的“对象”也变了。


>>> x = {"name":"qiwsir", "lang":["python", "java", "c"]}
>>> y = x.copy()
>>> y
{'lang':['python', 'java', 'c'], 'name': 'qiwsir'}
>>> id(x)
3072241012L
>>> id(x)
30722421284L
y是从x拷贝过来的,两个在内存中是不同的对象。


>>> y["lang"].remove("c")
>>> y
{'lang':['python','java'],'name': 'qiwsir'}
>>> x
{'lang':['python','java'],'name': 'qiwsir'}
这是什么原因呢?


>>> y["name"] = "laoqi"
>>> y
{'lang':['python','java'],'name': 'laoqi'}
>>> x
{'lang':['python','java'],'name': 'qiwsir'}
前面所说的原理是有效的,为什么到值是类别的时候就不能奏效了呢?


要破解这个迷局还得用di()
>>> id(x)
3072241012L
>>>  id(y)
3072241284L
y,y对应着两个不同对象,的确如此。单这个对象(字典)是由两个键值对组成的。


其中一个键的值是列表。


>>> id(x["lang"])
3072243276L
>>> id(y["lang"])
3072243276L
发现了这样一个事实,列表是同一对象。




但是,作为字符串为值得那个键值对,是分属不同对象。
>>> id(x["name"])
3072245184L
>>> id(y["name"])
3072245408L
这个事实,就说明了为什么修改一个列表,另外一个也跟着修改;而修改一个的字


符串,另外一个不跟随的原因了。


深层的原因,这跟python存储的数据类型特点有关,python只存储节本类型的数据


,比如in,str,对于不是基础类型的,比如刚才字典的值是列表,python不会再被


复制的那个对象中重新存储,而是用引用的方式,指向原来的值。


在python中,有一个“深拷贝(deep copy)”。不过,要用import来导入一个模块



>>> import copy
>>> z = copy.deepcopy(x)
>>> z
{'lang':['python','java'],'name':'qiwsir'}
用copy.deepcopy()深拷贝了一个新的副本。


>>> id(x["lang"])
3072243276L
>>> id(z["lang"])
3072245068L
果然是另外一个“窝”,不是引用了。如果按照这个结果,修改其中一个列表中的


元素,应该不影响另外一个了。


>>> x
{'lang':['python', 'java'], 'name': 'qiwsir'}
>>> x["lang"].remove("java")
>>> x
{'lang':['python'], 'name': 'qiwsir'}
>>> z
{'lang':['python', 'java'], 'name': 'qiwsir'}


>>> x["lang"].append("c++")
>>> x
{'lang':['python', 'c++'], 'name': 'qiwsir'}
这就是所谓浅拷贝和深拷贝。




clear
在交互模式中,用help是一个很多的习惯。


>>> help(dict.clear)


clear(...)
    D.clear() -> Nonee. Remove all items from D.
这是一个清空字典中所有元素的操作。


>>> a = {"name":"qiwsir"}
>>> a.clear()
>>> a
{}
这就是clear的含义,将字典清空,得到的是“空”字典。这个上节说的del有着很


大的区别。del是将字典删除,内存中就没有它了,不是为“空”。


>>> del a
>>> a
NameError: name 'a' is not defined
果然删除了。






get,setdefault


>>> d
{'lang': 'python'}
>>> d.get("lang")
'python'


dict.get()就是要得到字典中某个键的值,不过,它不是那么“严厉”罢了。因为


类似获得字典中键的值得方法,上节已经有过,如d['lang']就能得到对应的


值"python",可是,如果要获取的键不存在:


>>> print d.get("name")
None


>>> d["name"]
keyError: 'name'
这就是dict.get()和dict['key']的区别。


>>> d = {"lang":"python"}
>>> newd = d.get("name", 'qiwsir')
>>> newd
'qiwsir'
>>> d
{'lang': 'python'}
以d.get("name", 'qiwsir')的方式,如果不能得到键"name"的值,就返回后面指定


的值"qiwsir"。这就是文档中那句话,D[k] if k in D, else d.的含义。




另外一个跟get在功能上有相识地方的D.setdefault(k),其含义是:
>>> d
{'lang':'python'}
>>> d.setdefault("lang")
'python'
在字典中,有"lang"这个键,那么就返回它的值。


>>> d.setdefault("name", "qiwsir")
'qiwsir'
>>> d
{'lang': 'python', 'name': 'qiwsir'}
没有"name"这个键,于是返回d.setdefault("name","qiwsir")指定的值"qiwsir",
并且将键值对'name':'qiwsir'添加到原来的字典中。


如果这样操作:
>>> d.setdefault("web")
返回了,只不过没有显示出来。返回None
>>> d
{'lang': 'python','web': None, 'name': 'qiwsir'}




items/iteritems,keys/iterkeys,values/itervalues


D.items()能够得到一个关于字典的列表,列表中的元素是由字典中的键和值组成的


元组。
>>> dd = {"name":"qiwsir", "lang":"python", "web":"www.itdiffer.com"}
>>> dd_kv = dd.items()
>>> dd_kv
[('lang','python'),('web', 'www.itdiffer.com'),('name', 'qiwsir')]


跟items类似的就是iteritems,看这个词的特点,是由iter和items拼接而成的,后


部分items就不用说了,肯定是在告诉我们,得到的结果跟D.items()的结果类似。


是的,iterable,它的含义是“可迭代的”,这里的iter是指的名词iterator的前


部分,意思是“迭代器”。合起来,"iteritems"的含义就是:


>>> dd
{'lang': 'python', 'web':'www.itdiffer.com', 'name': 'qiwsir'}
>>> dd_iter = dd.iteritems()
>>> type(dd_iter)
<type 'dictionary-itemiterator'>
>>> dd_iter
<dictionary-itemiterator object at 0xb72b9a2c>
>>> list(dd_iter)
[('lang','python'),('web', 'www.itdiffer.com'),('name', 'qiwsir')]
得到的dd_iter的类型,是一个'dictionary-itemiterator'类型,不过这种迭代器


类型的数据不能直接输出,必须用list()转换一下,才能看到里面的真面目。


>>> dd
{'lang': 'python', 'web': 'www.itdiffer.com', 'name': 'qiwsir'}
>>> dd.keys()
['lang', 'web', 'name']
>>> dd.values()
['python', 'www.itdiffer.com','qiwsir']






pop,popitem


在列表(3)中,有关于删除列表中元素的函数pop和remove,这两个的区别在于


list.remove(x)用来删除指定的元素,而list.pop([i])用于删除指定索引的元素,


如果不提供索引值,就默认删除最后一个。


>>> dd
{'lang': 'python','web': 'www.itdiffer.com', 'name': 'qiwsir'}
>>> dd.pop("name")
'qiwsir'
"'name':'qiwsir'"这个键值对就被删除了。


>>> dd
{'lang': 'python','web': 'www.itdiffer.com'}


值得注意的是,pop函数中的参数是不能省略的,这跟列表中的那个pop有所不同。
>>> dd.pop()
TypeError:pop expected an least 1 arguments,got 0


如果要删除字典中没有的键值对,也会报错。
>>> dd.pop("name")
keyError:'name'


D.pop(k[,d])是以字典的键为参数,删除指定键的键值对。
pop的参数,可以是两个,上面的例子中只写了一个。如果写两个,那么就先检查K


是不是存在于字典中的键,如果是,就返回它所对应的值,如果不是,就返回参数


中的第二个,当然,如果不写第二个参数,就会如同上面举例一样报错。




有意思的是D.popitem()倒是跟list.pop()有相似之处,不用写参数(list,pop是可


以不写参数),但是,D.popitem()不是删除最后一个,前面已经交代过了,dict没


有顺序,也就没有最后和最先了,它是随机删除一个,并将所删除的返回。


popitem(...)
   D.popitem() -> (k,v),remove and return some (key, value) pair as a 2-


tuple; but raise keyError if D is empty.
如果字典是空的,就要报错了


>>> dd
{'lang': 'python', 'web': 'www.itdiffer.com'}
>>> dd.popitem()
('lang', 'python')
>>> dd
{'web': 'www.itdiffer.com'}
成功地删除了一对,注意是随机的,不是删除前面显示的最后一个。并且返回了删


除的内容,返回的数据格式是tuple。


>>> dd.popitem()
('web', 'www.itdiffer.com')
>>> dd
{}
都删了,现在那个字典成空的了。


>>> dd.popitem()
keyErro:'popitem(): dictionary is empty'






update
更新字典内容


>>> d1 = {"lang":"python"}
>>> d2 = {"song":"I dreamed a dream"}
>>> d1.update(d2)
>>> d1
{"lang":"python", "song":"I dreamed a dream"}
>>> d2
{"song":"I dreamed a dream"}
这样就把字典d2更新入了d1那个字典,于是d1中就多了一些内容,把d2的内容包含


进来了。d2当然还存在,并没有受到影响。


>>> d2
{"song":"I dreamed a dream"}
>>> d2.update([("name","qiwsir"),("web","itdiffer.com")])
>>> d2
{'web': 'itdiffer.com', 'name': 'qiwsir','song': 'I dreamed a dream'}
列表的元组是键值对。




has_key
这个函数的功能是判断字典中是否存在某个键


跟前一节中遇到的 k in D类似


>>> d2
{'web': 'itdiffeer.com', 'name': 'qiwsir', 'song': 'I dreamde a dream'}
>>> d2.has_key("web")
True
>>> "web" in d2
True

1
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:126641次
    • 积分:4029
    • 等级:
    • 排名:第8011名
    • 原创:273篇
    • 转载:56篇
    • 译文:0篇
    • 评论:5条
    最新评论