python学习笔记(五)之字典2
编程实战中经常用到
实例1:copy
>> ad = {"name":"wtf","hig":"180"}
>> bd = ad
>> bd
{'name': 'wtf', 'hig': '180'}
>> id (ad)
4539954352
>> id (bd)
4539954352
说明:一个对象贴上两个标签,使用赋值,实现了所谓的“假装拷贝”。
如果使用copy()
>> cd = ad.copy()
>> cd
{'name': 'wtf', 'hig': '180'}
>> id (cd)
4541831160
说明:这次得到的cd于原来的ad是不同的。
如果我修改cd,就应该对原来的ad不会造成什么影响,如下:
>> cd["name"] = "didi"
>> cd
{'name': 'didi', 'hig': '180'}
>> ad
{'name': 'wtf', 'hig': '180'}
如果我修改了bd,则ad也应该跟着改变的,如下:
>> bd["name"] = "aaa"
>> bd
{'name': 'aaa', 'hig': '180'}
>> ad
{'name': 'aaa', 'hig': '180'}
关于python中的浅拷贝与深拷贝
浅拷贝
实例2:元组中含有列表
>> x = {"name":"wtf","lang":["python","java"]}
>> type(x)
<type 'dict'>
>> y = x.copy()
>> y
{'lang': ['python', 'java'], 'name': 'wtf'}
>> id(x)
4529826624
>> id(y)
4529826344
说明:y是从x拷贝过来的,两个在内存中是不同的对象。
现在键“lang”的值是一个列表,为['python', 'java'],这里用remove()这个列表方法删除其中的一个元素“java”。删除之后,这个列表就变为:['python'],操作如下:
>> y["lang"].remove("java")
>> y
{'lang': ['python'], 'name': 'wtf'}
按照实例1,它是另一个对象,x应该是不会改变的,则:
>> x
{'lang': ['python'], 'name': 'wtf'}
x竟然改变啦!!
下面我们使用id()来分析下:
>> id(x)
4529826624
>> id(y)
4529826344
说明:x,y确实对应着两个不同的对象,但是这个对象(字典)是由两个键值组成的,其中一个键的值是列表。
>> id(x["lang"])
4529661856
>> id(y["lang"])
4529661856
说明:列表竟然是同一个对象!!
原因解释:
python在所执行的复制动作中,如果是基本类型的对象(专值数字和字符串),就在内存中重新建个窝;如果不是基本类型的,就不建新窝,而是用标签引用原来的窝。
深拷贝
python中的深拷贝就是使用import来导入一个模块。
实例3:
>> import copy
>> z = copy.deepcopy(x)
>> z
{'lang': ['python'], 'name': 'wtf'}
>> id(x["lang"])
4529661856
>> id(z["lang"])
4529828136
说明:果然是新建了一个窝,而不是引用啦!
此时,如果修改其中一个,应该不影响另一个。
实例4:
>> x
{'lang': ['python'], 'name': 'wtf'}
>> x["lang"].remove("python")
>> x
{'lang': [], 'name': 'wtf'}
>> z
{'lang': ['python'], 'name': 'wtf'}
clear
说明:在交互模式下,用help()是一个很好的习惯。
clear是一个清空字典中所有元素的操作
实例5:
>> x
{'lang': [], 'name': 'wtf'}
>> x.clear()
>> x
{}
说明:将字典清空,得到一个“空”字典。
del()是将字典删除,内存中就没有它了,不是为“空”。
实例6:
>> y
{'lang': [], 'name': 'wtf'}
>> del(y)
>> y
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'y' is not defined
get,setdefault
get的含义是:
help(dict.get)
get(...)
D.get(k[,d]) -> D[k] if k in D, else d. d defaults to None.
说明:“if k in D”,就返回其值
实例7:
>> d
{'lang': 'python'}
>> d.get("lang")
'python'
说明:dict.get()就是要得到字典中某个键的值,其实,
>> d["lang"]
'python'
也可以得到。
但是,如果是不存在的值,则:
实例8:
>> print d.get("name")
None
>> d["name"]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'name'
说明:这就是dict.get()与dict["key]的区别。
前面有一个半句话,如果键不在字典中,会返回none,这是一种情况。还可以这样:
实例9:
>> d
{'lang': 'python'}
>> newd = d.get("name","didi")
>> newd
'didi'
>> d
{'lang': 'python'}
说明:以d.get("name","didi")的方式,如果不能得到键"name"的值,就返回后面指定的值"didi"。这就是文档中D.get(k[,d]) -> D[k] if k in D, else d.的含义。这样做,并没有影响原来的字典。
setdefault
help(dict.setdefault)
含义:D.setdefault(k[,d]) -> D.get(k,d), also set D[k]=d if k not in D
说明:与get的功能上有相似的地方。
实例10:
>> d
{'lang': 'python'}
>> d.setdefault("lang")
'python'
>> d.setdefault("name","didi")
'didi'
>> d
{'lang': 'python', 'name': 'didi'}
说明:没有"name"这个键,于是就返回d.setdefault("name","didi")指定的值"didi",并且将键值对"name":"didi"添加到原来的字典中。
如果是这样的:
实例11:
>> d.setdefault("web")
>> print d
{'lang': 'python', 'web': None, 'name': 'didi'}
说明:键"web"的值变成了“None”
items/iteritems,keys/iterkeys,values/itervalues
说明:在pytho3中不再需要:iteritems,iterkeys,itervalues
➜ ~ python --version
Python 2.7.10
>> help(dict.items)
items(...)
D.items() -> list of D's (key, value) pairs, as 2-tuples
实例12:
>> dd = {"name":"wtf","lang":"java","web":"www.datagrand.com"}
>> dd_kv = dd.items()
>> dd_kv
[('lang', 'java'), ('web', 'www.datagrand.com'), ('name', 'wtf')]
说明:这种操作对循环有大用。>> help(dict.iteritems)
iteritems(...)
D.iteritems() -> an iterator over the (key, value) items of D
实例13:
>> dd
{'lang': 'java', 'web': 'www.datagrand.com', 'name': 'wtf'}
>> dd_iter = dd.iteritems()
>> type(dd_iter)
<type 'dictionary-itemiterator'>
>> dd_iter
<dictionary-itemiterator object at 0x106f56a48>
>> list(dd_iter)
[('lang', 'java'), ('web', 'www.datagrand.com'), ('name', 'wtf')]
说明:得到的dd_iter的类型,是一个“dictionary-itemiterator”类型,不过这种迭代器类型的数据不能直接输出,必须用list()转换一下,才能看到里面的真面目。
另外两组与item/iteritems含义相似。
pop,popitem
说明:在列表中,有关删除列表中元素的函数pop和remove,这两个的区别在于:list.remove(x)用来删除指定的元素,而list.pop[i]用来删除指定索引的元素,如果不提供索引值,就默认删除最后一个。
在字典中,也有删除键值对的函数
>> help(dict.pop)
pop(...)
D.pop(k[,d]) -> v, remove specified key and return the corresponding value.
If key is not found, d is returned if given, otherwise KeyError is raised
其中,D.pop(k[,d])是以字典的键为参数,删除指定键的键值对。
实例14:
>> dd
{'lang': 'java', 'web': 'www.datagrand.com', 'name': 'wtf'}
>> dd.pop("name")
'wtf'
>> dd
{'lang': 'java', 'web': 'www.datagrand.com'}
值得注意的是,字典中pop函数的参数是不能省略的,这跟列表中的那个pop有所不同。
实例15:
>> dd.pop()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: pop expected at least 1 arguments, got 0
如果删除字典中没有的键值对,也会报错:
实例16:
>> dd
{'lang': 'java', 'web': 'www.datagrand.com'}
>> dd.pop("name")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'name'
popitem
>> help(dict.popitem)
popitem(...)
D.popitem() -> (k, v), remove and return some (key, value) pair as a
2-tuple; but raise KeyError if D is empty.
说明:D.popitem()与list.pop()有相似之处。
实例17:
>> dd
{'lang': 'java', 'web': 'www.datagrand.com'}
>> dd.popitem()
('lang', 'java')
>> dd
{'web': 'www.datagrand.com'}
说明:随机删除一对
>> dd.popitem()
('web', 'www.datagrand.com')
>> dd
{}
已经把字典变成空,再删:
>> dd.popitem()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'popitem(): dictionary is empty'
说明:告知没有东西可删除啦
update
说明:更新字典
>> help(dict.update)
update(...)
D.update([E, ]**F) -> None. Update D from dict/iterable E and F.
If E present and has a .keys() method, does: for k in E: D[k] = E[k]
If E present and lacks .keys() method, does: for (k, v) in E: D[k] = v
In either case, this is followed by: for k in F: D[k] = F[k]
说明:这个函数没有返回值,或者说返回值是none,它的作用就是更新字典。其参数可以是字典或者某种可迭代的对象。
实例18:
>> d1 = {"lang":"python"}
>> d2 = {"name":"wtf"}
>> d1.update(d2)
>> d1
{'lang': 'python', 'name': 'wtf'}
>> d2
{'name': 'wtf'}
说明:字典d2更新入了d1那个字典,于是d1中就多了一些内容,把d2的内容包含了进来,d2内容保持不变。
还可以以下面这种方式更新:
实例19:
>> d2
{'name': 'wtf'}
>> d2.update([("song","xingxing"),("web","www.baidu.com")])
>> d2
{'web': 'www.baidu.com', 'name': 'wtf', 'song': 'xingxing'}
has_key
说明:目前仅在python2中存在,python3中将其取消了
这个函数的功能就是判断字典中是否存在某个键,跟"k in d"类似。
>> help(dict.has_key)
has_key(...)
D.has_key(k) -> True if D has a key k, else False
实例20:
>> d2
{'web': 'www.baidu.com', 'name': 'wtf', 'song': 'xingxing'}
>> d2.has_key("web")
True