dict的一些用法

字典基础参考:
【1】:http://www.w3cschool.cc/python/python-dictionary.html
【2】:http://www.111cn.net/phper/python/56355.htm
【3】:http://skyfen.iteye.com/blog/567571
【4】:http://www.cnblogs.com/rubylouvre/archive/2011/06/19/2084739.html

1.使用dict创建字典的n种方法


除了我们比较常用的d = {'a':1, 'b':2}来初始化字典外,还可以使用dict()来初始化,这种方法更为灵活。以下介绍了用dict来初始化字典的几种方法。

在交互窗口输入:dict?

便会出现创建dict的方法

dict?
Init signature: dict(self, /, *args, **kwargs)
Docstring:     
dict() -> new empty dictionary
dict(mapping) -> new dictionary initialized from a mapping object's
    (key, value) pairs
dict(iterable) -> new dictionary initialized as if via:
    d = {}
    for k, v in iterable:
        d[k] = v
dict(**kwargs) -> new dictionary initialized with the name=value pairs
    in the keyword argument list.  For example:  dict(one=1, two=2)
Type:           type

在交互窗口输入:help(dict)

不仅会出现创建dict的方法,还会有更多的内容

2.参数赋值

In [6]: d = dict(a=1,b=2)
In [7]: d
Out[7]: {'a': 1, 'b': 2}


用可迭代对象为参数,且每一个迭代对象为(k, v)对

In [8]: l1 = ['a', 'b', 'c']
In [9]: l2 = [1, 2, 3]
In [11]: zip(l1,l2)
Out[11]: [('a', 1), ('b', 2), ('c', 3)]
In [12]: d = dict(zip(l1,l2))
In [13]: d
Out[13]: {'a': 1, 'b': 2, 'c': 3}


字典推导式(dictionary comprehension)
如同列表推导式,我们可以使用字典推导式来很简洁的生成一些字典。

In [14]: d = { c:ord(c) for c in 'abc' }
In [15]: d
Out[15]: {'a': 97, 'b': 98, 'c': 99}


设置默认值
已经知道key的情况下批量生成默认值
如有一个列表=['a', 'b', 'c'],要将其中的值作为key,值全部设为0。可以使用dict.fromkeys()来完成:

同样,可以用d.fromkeys?来看一下fromkeys的具体使用方法

In [17]: l = ['a','b','c']
In [18]: d = {}
In [19]: d.fromkeys(l, 0)
Out[19]: {'a': 0, 'b': 0, 'c': 0}
若第二个参数不传入则默认为None。

如要对一段字符文本s = 'hello, world!'进行字符统计(事先不知道会有哪些key),将结果保存在字典中。
由于事先不知道会有哪些key,因此在一个新的值传入时,需要先判断该值是否在字典中,若存在,则加1,否则置为1。代码如下:

d = {}
s = 'hello, world!'
for c in s:
    if c in d:
        d[c] += 1
    else:
        d[c] = 1

使用defaultdict
defaultdict是collections中提供的设置了默认值的字典类型。

from collections import defaultdict
s = 'hello, world!'
d = defaultdict(int)
for c in s:
    d[c] += 1
print(d)

使用setdefault方法来实现同时设置默认值和取值
dict自带的setdefault方法,会在key存在时返回value,若不存在,则设为指定值并返回这个值。如:

In [29]: d = {'a':1, 'b':2}
In [30]: d.setdefault('a', 3)
Out[30]: 1
In [31]: d.setdefault('c', 3)
Out[31]: 3
In [32]: d
Out[32]: {'a': 1, 'b': 2, 'c': 3}

用这个方法实现上述功能为:

In [26]: d2 = {}
In [27]: for c in s: d2[c] = d2.setdefault(c, 0) + 1
In [28]: d2
Out[28]:
{' ': 1,
 '!': 1,
 ',': 1,
 'd': 1,
 'e': 1,
 'h': 1,
 'l': 3,
 'o': 2,
 'r': 1,
 'w': 1}

由此可见,在这种情况下,使用setdefault可以写出和使用defaultdict方法同样简洁的代码。

3.删除字典中的元素

pop方法
python字典的pop方法会在键存在时返回该值,同时从字典中删除该键,若不存在可以返回默认值。

In [33]: d
Out[33]: {'a': 1, 'b': 2, 'c': 3}
In [34]: d.pop('a')
Out[34]: 1
In [35]: d
Out[35]: {'b': 2, 'c': 3}
In [36]: d.pop('d')
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-36-ee5e0ecd6e46> in <module>()
----> 1 d.pop('d')
 
KeyError: 'd'
 
In [37]: d.pop('d', 0)
Out[37]: 0

在判断一个特殊的字典并进行处理的时候非常有用。
假定我们有一个处理字典的函数:

def process_dict(d):
   dosomething(d)

它接收所有人的字典并进行处理。假定现在你传入的字典需要进行一些其他的特殊处理,如何让函数识别传入的是你的字典并且不产生副作用呢?
我们可以将函数改为:

def process_dict(d):
    if d.pop('is_mine', False):
        do_something_special(d)
    dosomething(d)

然后对于你要传入的字典设定k['is_mine']=True再传入该函数,进入函数后pop方法会将其弹出,识别出这是你的,进行一些操作,再继续。对于不存在该key的字典来说,返回False,不产生任何副作用。

4. 遍历字典的n种方法

d.keys(),d.values(),d.items()分别返回键,值,键值对的列表。

5.字典的复制

类似于list的复制

(1)  dict2 = dict1 
如果你修改a,那你就同时修改了b,因为它们指向同一个列表:

>>> a = {'f': 1, 'b':2, 'c':[1, 2]}
>>> b = a
>>> a['f'] = 3
>>> print a
{'f': 3, 'b':2, 'c':[1, 2]}
>>> print b
{'f': 3, 'b':2, 'c':[1, 2]}


内建函数id()可以返回对象的唯一id。该id是对象的内存地址。

>>> id(a)

4460668248
>>> id(b)

4460668248
>>> c = {} # Create a new dict
>>> id(c)

4460637424


可以看出a和b都指向同一个内存地址。c指向一个新建的空字典,因此指向了不同的地址。

(2)用dict() 字典构造函数

>>> b = dict(a)
>>> id(a)

4460609992
>>> id(b)

4460697288

(3)dict的复制方法汇总

import copy
a = {'a':1,'b':{'b':2}}
b = a
c = dict(a)
d = copy.copy(a)
e = copy.deepcopy(a)
a['a']=2
a['b']['c'] = 3
print(a)
print(id(a))

{'a': 2, 'b': {'b': 2, 'c': 3}}
4460668608

print(b)
print(id(b))

{'a': 2, 'b': {'b': 2, 'c': 3}}
4460668608

print(c)
print(id(c))

{'a': 1, 'b': {'b': 2, 'c': 3}}
4460635768

print(d)
print(id(d))

{'a': 1, 'b': {'b': 2, 'c': 3}}
4460824688

print(e)
print(id(e))

{'a': 1, 'b': {'b': 2}}
4460637856

 
从以上可以看出 dict(a), copy.copy(a), copy.deepcopy('a') 三种方式复制字典结果都可以得到一个新的字典,但是如果字典中含有字典,所有b, c, d四个新字典的子列表都是指引到同一个对象上。只有使用copy.deepcopy(a)方法得到的新字典e才是包括子字典在内的完全复制。

猜你喜欢

转载自blog.csdn.net/zhao_crystal/article/details/83070122