在Python中字典(dict)是一种key value
的数据类型,使用就像我们上学用的字典,通过笔划、字母来查对应页的详细内容,同时在所有数据类型中使用频率也是相当高的,而且它的访问方式是通过键来获取到对应的值,属于可变类型,其中字典的Key必须是不可变类型,比如字符串、数字、元组都可以作为字典的Key,但是Value可以是任何对象。
字典是Python中最优秀的特性之一,许多高效、优雅的算法即以此为基础。
那这里总结一下字典的特征:
- 字典是序列类型,但是是无序序列,所以没有分片和索引;
- 字典中的数据每个都有键值对组成,即KV对;
- Key必须是可哈希的值,比如int,string,float,tuple, 但是,list,set,dict 不行;
- Value任何值均可
字典的增删改查
1.字典的创建:
1.1 常规方法:
>>> personal_file = {'job': 'iter', 'age': 18, 'hometown': 'NanChang'}
>>> type(personal_file)
<type 'dict'>
>>> print(personal_file)
{'hometown': 'NanChang', 'job': 'iter', 'age': 18}
1.2 fromkeys方法:
Python字典fromkeys()
函数用于创建一个新字典,以序列seq
中元素做字典的键,value
为字典所有键对应的初始值。
fromkeys()
方法语法:
dict.fromkeys(seq[, value])
seq --> 字典键值列表
value --> 可选参数, 设置键序列(seq)的值。
>>> name_list = ['Tom', 'Jim', 'Nock']
>>> personal_file = dict.fromkeys(name_list, 10)
>>> print(personal_file)
{'Jim': 10, 'Nock': 10, 'Tom': 10}
>>> personal_file = dict.fromkeys(name_list, (10,9,8))
>>> print(personal_file)
{'Jim': (10, 9, 8), 'Nock': (10, 9, 8), 'Tom': (10, 9, 8)}
>>> personal_file = dict.fromkeys(name_list)
>>> print(personal_file)
{'Jim': None, 'Nock': None, 'Tom': None}
# 创建的personal_file的value值指向同一块内存空间,这就有些类似浅拷贝了
fromkeys也就是不给初值时默认为None,给初值的话为所有键的值为初值。
更多组合其他函数使用创建请阅读: https://fashengba.com/post/python-create-dict-method.html
2. 字典的访问:
>>> name_info = {'Jim': 20, 'Nock': 18, 'Tom': 21}
>>> name_info['Nock']
18
>>> name_info['Nocks']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'Nocks'
# 如果字典里面不存在某个'key',获取就会报KeyError的错误信息
>>> name_info.get('Nock')
18
>>> name_info.get('Nocks')
>>> print(name_info.get('Nocks'))
None
>>> name_info.get('Nocks','default_custome')
'default_custome'
# .get 方法比较友好,如果不存在的'key'默认返回None,但是你可以设置默认值get(key, default=)
如果要100%确认字典拥有的key
,才去获取他的值,那应该怎么做呢,参考:https://fashengba.com/post/python-determines-key-in-dict.html,利用in
关键字即可:
>>> name_info = {'Jim': 20, 'Nock': 18, 'Tom': 21}
>>> if 'Nocks' in name_info:
... print(name_info['nocks'])
... else:
... print('dict not key "Nocks"!')
...
dict not key "Nocks"!
>>> if 'Jim' in name_info: name_info['Jim']
...
20
3. 字典的添加:
>>> name_info = {'Jim': 20, 'Nock': 18, 'Tom': 21}
>>> name_info['Cat'] = 21
>>> name_info
{'Tom': 21, 'Cat': 21, 'Jim': 20, 'Nock': 18}
# 不存在才添加,存在就是修改了
update字典添加到字典里面:
>>> name_info = {'Jim': 20, 'Nock': 18, 'Tom': 21}
>>> add_name = {'lucky': 19, 'Jerry': 30}
>>> name_info.update(add_name)
>>> print(name_info)
{'Tom': 21, 'Jerry': 30, 'Jim': 20, 'lucky': 19, 'Nock': 18}
4. 字典的修改:
>>> name_info = {'Jim': 20, 'Nock': 18, 'Tom': 21}
>>> name_info['Jim'] = 30
>>> name_info
{'Tom': 21, 'Jim': 30, 'Nock': 18}
5. 字典的删除:
>>> name_info = {'Jim': 20, 'Nock': 18, 'Tom': 21}
>>> name_info.pop('Jim') # 标准删除,有返回值
20
>>> name_info
{'Tom': 21, 'Nock': 18}
>>> del name_info['Tom'] # del方法删除,无返回
>>> name_info
{'Nock': 18}
>>> name_info = {'Jim': 20, 'Nock': 18, 'Tom': 21}
>>> name_info.popitem() # 随机删除,返回元组
('Tom', 21)
>>> name_info.popitem()
('Jim', 20)
>>> name_info
{'Nock': 18}
清空字典:
>>> name_info = {'Jim': 20, 'Nock': 18, 'Tom': 21}
>>> del name_info # 从内存中抹掉
>>> name_info
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'name_info' is not defined
>>> name_info = {'Jim': 20, 'Nock': 18, 'Tom': 21}
>>> name_info.clear() # 清空字典里面数据,变为空字典
>>> name_info
{}
字典其他方法
class dict(object):
"""
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)
"""
def clear(self): # real signature unknown; restored from __doc__
""" 清除内容 """
""" D.clear() -> None. Remove all items from D. """
pass
def copy(self): # real signature unknown; restored from __doc__
""" 浅拷贝 """
""" D.copy() -> a shallow copy of D """
pass
@staticmethod # known case
def fromkeys(S, v=None): # real signature unknown; restored from __doc__
"""
dict.fromkeys(S[,v]) -> New dict with keys from S and values equal to v.
v defaults to None.
"""
pass
def get(self, k, d=None): # real signature unknown; restored from __doc__
""" 根据key获取值,d是默认值 """
""" D.get(k[,d]) -> D[k] if k in D, else d. d defaults to None. """
pass
def has_key(self, k): # real signature unknown; restored from __doc__
""" 是否有key """
""" D.has_key(k) -> True if D has a key k, else False """
return False
def items(self): # real signature unknown; restored from __doc__
""" 所有项的列表形式 """
""" D.items() -> list of D's (key, value) pairs, as 2-tuples """
return []
def iteritems(self): # real signature unknown; restored from __doc__
""" 项可迭代 """
""" D.iteritems() -> an iterator over the (key, value) items of D """
pass
def iterkeys(self): # real signature unknown; restored from __doc__
""" key可迭代 """
""" D.iterkeys() -> an iterator over the keys of D """
pass
def itervalues(self): # real signature unknown; restored from __doc__
""" value可迭代 """
""" D.itervalues() -> an iterator over the values of D """
pass
def keys(self): # real signature unknown; restored from __doc__
""" 所有的key列表 """
""" D.keys() -> list of D's keys """
return []
def pop(self, k, d=None): # real signature unknown; restored from __doc__
""" 获取并在字典中移除 """
"""
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
"""
pass
def popitem(self): # real signature unknown; restored from __doc__
""" 获取并在字典中移除 """
"""
D.popitem() -> (k, v), remove and return some (key, value) pair as a
2-tuple; but raise KeyError if D is empty.
"""
pass
def setdefault(self, k, d=None): # real signature unknown; restored from __doc__
""" 如果key不存在,则创建,如果存在,则返回已存在的值且不修改 """
""" D.setdefault(k[,d]) -> D.get(k,d), also set D[k]=d if k not in D """
pass
def update(self, E=None, **F): # known special case of dict.update
""" 更新
{'name':'alex', 'age': 18000}
[('name','sbsbsb'),]
"""
"""
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]
"""
pass
def values(self): # real signature unknown; restored from __doc__
""" 所有的值 """
""" D.values() -> list of D's values """
return []
def viewitems(self): # real signature unknown; restored from __doc__
""" 所有项,只是将内容保存至view对象中 """
""" D.viewitems() -> a set-like object providing a view on D's items """
pass
def viewkeys(self): # real signature unknown; restored from __doc__
""" D.viewkeys() -> a set-like object providing a view on D's keys """
pass
def viewvalues(self): # real signature unknown; restored from __doc__
""" D.viewvalues() -> an object providing a view on D's values """
pass
def __cmp__(self, y): # real signature unknown; restored from __doc__
""" x.__cmp__(y) <==> cmp(x,y) """
pass
def __contains__(self, k): # real signature unknown; restored from __doc__
""" D.__contains__(k) -> True if D has a key k, else False """
return False
def __delitem__(self, y): # real signature unknown; restored from __doc__
""" x.__delitem__(y) <==> del x[y] """
pass
def __eq__(self, y): # real signature unknown; restored from __doc__
""" x.__eq__(y) <==> x==y """
pass
def __getattribute__(self, name): # real signature unknown; restored from __doc__
""" x.__getattribute__('name') <==> x.name """
pass
def __getitem__(self, y): # real signature unknown; restored from __doc__
""" x.__getitem__(y) <==> x[y] """
pass
def __ge__(self, y): # real signature unknown; restored from __doc__
""" x.__ge__(y) <==> x>=y """
pass
def __gt__(self, y): # real signature unknown; restored from __doc__
""" x.__gt__(y) <==> x>y """
pass
def __init__(self, seq=None, **kwargs): # known special case of dict.__init__
"""
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)
# (copied from class doc)
"""
pass
def __iter__(self): # real signature unknown; restored from __doc__
""" x.__iter__() <==> iter(x) """
pass
def __len__(self): # real signature unknown; restored from __doc__
""" x.__len__() <==> len(x) """
pass
def __le__(self, y): # real signature unknown; restored from __doc__
""" x.__le__(y) <==> x<=y """
pass
def __lt__(self, y): # real signature unknown; restored from __doc__
""" x.__lt__(y) <==> x<y """
pass
@staticmethod # known case of __new__
def __new__(S, *more): # real signature unknown; restored from __doc__
""" T.__new__(S, ...) -> a new object with type S, a subtype of T """
pass
def __ne__(self, y): # real signature unknown; restored from __doc__
""" x.__ne__(y) <==> x!=y """
pass
def __repr__(self): # real signature unknown; restored from __doc__
""" x.__repr__() <==> repr(x) """
pass
def __setitem__(self, i, y): # real signature unknown; restored from __doc__
""" x.__setitem__(i, y) <==> x[i]=y """
pass
def __sizeof__(self): # real signature unknown; restored from __doc__
""" D.__sizeof__() -> size of D in memory, in bytes """
pass
__hash__ = None
字典嵌透
# 在列表中嵌透字典
to_do_list = [
{'name': 'Tom', 'age': 20, 'job': 'dev'},
{'name': 'nock', 'age': 18, 'job': 'devops'}
]
# 字典中嵌透列表和字典, Example: Zabbix Discovery
discovery_data = {
"data": [
{
"{#CONSUMER_GROUP}": "JavaConsumer",
"{#TOPIC_NAME}": "javaAgentTopic",
"{#PARTITION_NUM}": "0"
},
{
"{#CONSUMER_GROUP}": "HostConsumer",
"{#TOPIC_NAME}": "hostAgentTopic",
"{#PARTITION_NUM}": "0"
}
]
}
字典的遍历
name_info = {'Jim': 20, 'Nock': 18, 'Tom': 20, 'Jerry': 25}
# 键值 会先把dict转成list,数据里大时莫用
for k, v in name_info.items():
print('Dict name_info key is: %s, value is: %s' % (k, v))
# 按照Key循环 sorted按照key排序
for k in name_info.keys():
print(k)
for k in name_info:
print(k)
for k in sorted(name_info.keys()):
print(k)
# 按照Value循环 set去重
for v in name_info.values():
print(v)
for v in set(name_info.values()):
print(v)
字典几种高阶使用场景
1. 字典作为计数器
假设给你一个字符串,你想计算每个字母出现的次数。使用字典的实现有一个优势,即我们不需要事先知道字符串中有几种字母, 只要在出现新字母时分配空间就好了。
def histogram(strings):
string_dict = dict()
for letter in strings:
string_dict[letter] = string_dict.get(letter, 0) + 1
return string_dict
测试:
print(histogram('apple'))
{'e': 1, 'l': 1, 'a': 1, 'p': 2}
设置一个直方图函数,利用字典的get方法,如果能够获取到则计数+1,如果没有,则就默认返回0+1
计数。
2. 字典逆向查找
给定一个字典words
以及一个键a,很容易找到相应的值 word_num = words['a'] 。 该运算被称作查找(lookup)。
但是如果你想通过word_num找到'a'呢? 有两个问题:第一,可能有不止一个的键其映射到值word_num。 你可能可以找到唯一一个,不然就得用list
把所有的键包起来。 第二,没有简单的语法可以完成 逆向查找(reverse lookup),你必须搜索。
下面这个函数接受一个值并返回映射到该值的第一个键:
def reverse_lookup(input_dict, find_value):
for dict_key in input_dict:
if input_dict[dict_key] == find_value:
return dict_key
raise LookupError('You find value %s does not appear in the dictionary' % find_value)
word_dict = {'a': 2, 'w': 1, 'r': 3, 'k': 1}
print(reverse_lookup(word_dict, 4))
逆向查找比正向查找慢得多,如果你频繁执行这个操作或是字典很大,程序性能会变差。
本文由 空心菜 创作,采用 知识共享署名4.0 国际许可协议进行许可
本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名
最后编辑时间为: Mar 17, 2020 at 04:10 pm