Python中的字典奥义

字典简介

  字典是一个键值对的集合。字典的键值可以是任何不可变(immutable)的数据类型,比如:字符串、数字、元组。字典的键值是无序互不相同的,就像是一个set,所以说字典的键值是set-like的。

元组作为键值时要注意,元组中的元素必须是不可变的数据类型,不能是列表等可变(mutable)的数据类型。

字典的初始化

  1. 大括号
    tel = {'jack': 4098, 'sape': 4139}
  2. dict()
    dict([('sape', 4139), ('guido', 4127), ('jack', 4098)])
  3. 解析式
    {x: x**2 for x in (2, 4, 6)}
  4. 针对字符串键值的特殊情况
    dict(sape=4139, guido=4127, jack=4098)

字典的基本操作

>>> # dict的初始化
>>> tel = {'jack': 4098, 'sape': 4139}
>>> # 插入元素
>>> tel['guide'] = 4127
>>> tel
{'guide': 4127, 'jack': 4098, 'sape': 4139}

>>> # 提取元素
>>> tel['jack']
4098

>>> # 删除元素
>>> del tel['sape']
>>> tel['irv'] = 4127
>>> tel
{'guide': 4127, 'irv': 4127, 'jack': 4098}

>>> # 显示字典键值
>>> print(list(tel.keys()))
>>> # 显示字典键值并排序
>>> print(sorted(tel.keys()))
['jack', 'guide', 'irv']
['guide', 'irv', 'jack']

>>> # 判断键值是否包含于字典中
>>> print('guide' in tel)
>>> print('jack' not in tel)
True
False

字典的深入解析

  在数据结构中,MapCollection是两种并列的数据结构。dict就是Map类型的代表。Map类型中对键值的要求是hashable的。

官方文档:An object is hashable if has a hash value which never changes during its lifetime (ite needs a __hash__() method), and can be compared to other objects (it needs an __eq__() method).

  hashable在Python中的解释,如果一个对象是hashable的,说明它有一个__hash__属性,这应该是该对象在哈希表中的位置,比如一个字符串的__hash__属性:

>>> a = 'c'
>>> a.__hash__
<method-wrapper '__hash__' of str object at 0x000001C3ACD9B228>

  python中的列表不是hashable的,列表的hash属性,输出是空,即列表没有hash值,不是hashable的:

>>> l1 = [10, 1]
>>> l1.__hash__

  同时,hashable的另一个必要条件是__eq__(),即可比较的。Python中的==就是调用的__eq__()。

官方文档: All of Python’s immutable built-in objects are hashable; mutable containers (such as lists or dictionaries) are not. Objects which are instances of user-defined classes are hashable by default. They all compare unequal (except with themselves), and their hash value is derived from their id()

大意:Python中,所有的build-in对象都是hashable的,所有的可变容器(如list,dict)都不是hashable的。对象的哈希值由它们的id()决定。

PS:id()表示对象的存储位置。

hashable

hashable的两个条件:
-\ __hash__存在,即有哈希值
- __eq__()存在,即可比较


  用户自己创建的类默认hashable,但是它们互不相等,它们的hash值来自于它们的id()。看下面的例子:

>>> class object1():
>>>     def __init__(self):
>>>         self.a = 0
>>> # 类有hash值
>>> object1.__hash__
>>> # 类可比较,所以类是hashable
>>> object1 == object1
True
>>> object1.__hash__
<slot wrapper '__hash__' of 'object' objects>
>>> id(object1)
1939958360056

再来看它的实例:

>>> instance1 = object1()
>>> instance2 = object1()
>>> instance1 == instance2
>>> instance1.__hash__
<method-wrapper '__hash__' of object1 object at 0x000001C3AF584668>
>>> instance2.__hash__
<method-wrapper '__hash__' of object1 object at 0x000001C3AF584400>
>>> id(instance1)
1939972048488
>>> id(instance2)
1939972047872

  可以看到,类是没有hash值的,但是有id()值,python中的任何变量(或者说是对象)都有id()值,id()值表示该变量在内存中的存储位置。但是类的两个实例是有hash值的,并且不相等,所以instance1 not is instance2, 自然instance1 != instance2
PS:is比较的是变量的存储位置,==变量值是否相等

Python中的相等

  • is比较的是存储位置,即id()的值
  • ==比较的是值的大小,即使两个变量的存储位置不同,它们的值相同就是==的。

PS:有一点要注意,Python出于节约内存的目的,如果两个变量的值是相同的整形或者字符串,将使用同样的存储位置,所以:

>>> a = 2
>>> b = 2
>>> print(a is b, a == b)
True True
>>> id(a), id(b)
(1837933696, 1837933696)

字典中键值重复的情况

  重复键值时,Python解释器自动选择最后一个。但是:

>>> D = {1: 'a', 1.0: 'b'}
>>> D
{1: 'b'}

  字典中的键值要求是hashable,它们的比较方式是__eq__()也就是==,所以键值1和1.0是重合的。

字典的方法

>>> dir(D)
['__class__',
 '__contains__',
 ...
 '__subclasshook__',
 'clear',
 'copy',
 'fromkeys',
 'get',
 'items',
 'keys',
 'pop',
 'popitem',
 'setdefault',
 'update',
 'values']
方法
  • clear(): Remove all items from the dictionary.
  • copy(): Return a shallow 1 copy of the dictionary.
  • fromkeys(seq[,value]): Returns a new dictionary. value defaults to None.
  • get(key[,default]): Return the value for key if key is in the dictionary, else default. If default is not given, it defaults to None, so that this method never raise a KeyError
  • items(): Return a new view of the dictionary’s items ((key, value) pairs).
  • keys(): Return a new view of the dictionary’s keys.
  • pop(key[,default]): If key is in the dictionary, remove it and return its value, else return default. If default is not given and key is not in the dictionary, a KeyError is raised.
  • popitem(): Remove and return an arbitrary (key, value) pair from the dictionary. If the dictionary is empty, calling popitem() raise a KeyError.
  • setdefault(key[,default]): If key is in the dictionary, return its value. If not, insert key with a value of default and return default. default defaults to None
  • updata([other]): Update the dictionary with the key/value pairs from other, overwriting existing keys. Return None. update() accepts either another dictionary object or an iterable of key/value pairs (as tuples or other iterables of length two). If keyword arguments are specified, the dictionary is then updated with those key/value pairs: d.update(red=1, blue=2).
  • values(): Return a new view of the dictionary’s values.

字典的迭代

三种方式:

>>> dishes = {'eggs': 2, 'sausage': 1, 'bacon': 1, 'spam': 500}
>>> for k in dishes.items():
>>>     print(k)
('eggs', 2)
('sausage', 1)
('bacon', 1)
('spam', 500)
>>> for k in dishes:
>>>     print(k)
eggs
sausage
bacon
spam
>>> for k in dishes.values():
>>>     print(k)
2
1
1
500

  1. 深拷贝与浅拷贝:http://python.jobbole.com/82294/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值