您的位置:首页 > 编程语言 > Python开发

python 字典学习2

2016-05-30 14:47 417 查看
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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Python