Python3之字典(Dictionary)浅谈

日期:2019年11月25日
作者:Commas
注释:学习就是为了忘记,让我们来总结一下Python3字典的定义、11个元组方法的使用、遍历的方法…

如果您想了解更多有关Python的知识,那么请点【我】
《我的Python浅谈系列目录》



一、字典的定义

字典(Dictionary)和列表有些许类似,是有序的 (无序的)可变 的元素(键值对key:value)集合,每个值(value)都有一个唯一键(key)所对应,这个键就是对应值在字典的“索引”,即“字典[键名] = 值”。

RUNOOB.COM给出的字典定义:
字典是另一种可变容器模型,且可存储任意类型对象。
字典的每个键值 key=>value 对用冒号 : 分割,每个键值对之间用逗号 , 分割,整个字典包括在花括号 {} 中 ,格式如下所示:
d = {key1 : value1, key2 : value2 }

# (1)定义空字典
empty_dict = {}
# (2)定义一个键值对的字典
single_dict = {
    'abc': 'valueStr'
}
single_dict['abc'] # 值为valueStr
# (3)定义多个键值对的字典
score_dict = {'Chinese': 99, 'Math': 100, 'English': 98}
score_dict['Chinese']  # 99
score_dict['Math']     # 100
score_dict['English']  # 98

在这里插入图片描述

二、字典的方法

获取“字典方法”的方法如下:
Python语句:print(dir({}))
控制台输出:
[‘class’, ‘contains’, ‘delattr’, ‘delitem’, ‘dir’, ‘doc’, ‘eq’, ‘format’, ‘ge’, ‘getattribute’, ‘getitem’, ‘gt’, ‘hash’, ‘init’, ‘init_subclass’, ‘iter’, ‘le’, ‘len’, ‘lt’, ‘ne’, ‘new’, ‘reduce’, ‘reduce_ex’, ‘repr’, ‘setattr’, ‘setitem’, ‘sizeof’, ‘str’, ‘subclasshook’, ‘clear’, ‘copy’, ‘fromkeys’, ‘get’, ‘items’, ‘keys’, ‘pop’, ‘popitem’, ‘setdefault’, ‘update’, ‘values’]

  1. clear()
    D.clear() -> None. Remove all items from D.
    移除该字典的所有项(键值对),相当于清空字典
student_dict = {
    'Name': '小明',
    'Age': 18,
    'Class': 'First'
}
print(student_dict)
student_dict.clear()
print(student_dict)
# 控制台输出:
# {'Name': '小明', 'Age': 18, 'Class': 'First'}
# {}
  1. copy()
    D.copy() -> a shallow copy of D
    字典的浅复制,重新开辟内存空间
student_dict = {'name': '小明'}
print('浅复制结果:')
#(1)浅复制
copy_student_dict = student_dict.copy()
print('{0}的内存地址为:{1},其内容为{2}'.format(
    'copy_student_dict',
    id(copy_student_dict),
    copy_student_dict
))
copy_student_dict['name'] = "Commas"
print('{0}的内存地址为:{1},其内容为{2}'.format(
    'copy_student_dict',
    id(copy_student_dict),
    copy_student_dict
))
print('{0}的内存地址为:{1},其内容为{2}'.format(
    'copy_student_dict',
    id(student_dict),
    student_dict
))
print('深复制结果:')
# (2)深复制
equal_student_dict = student_dict
print('{0}的内存地址为:{1},其内容为{2}'.format(
    'copy_student_dict',
    id(equal_student_dict),
    equal_student_dict
))
equal_student_dict['name'] = "Commas"
print('{0}的内存地址为:{1},其内容为{2}'.format(
    'copy_student_dict',
    id(equal_student_dict),
    equal_student_dict
))
print('{0}的内存地址为:{1},其内容为{2}'.format(
    'copy_student_dict',
    id(student_dict),
    student_dict
))

(i)知识加油站:
① id(object)–> 获得 obj 的内存地址(10进制)
② 如果想比较系统的了解Python字符串格式化,请看《Python3之字符串格式化浅谈》
(ii)控制台输出:
浅复制结果:
copy_student_dict的内存地址为:1962127493592,其内容为{‘name’: ‘小明’}
copy_student_dict的内存地址为:1962127493592,其内容为{‘name’: ‘Commas’}
copy_student_dict的内存地址为:1962128181144,其内容为{‘name’: ‘小明’}
深复制结果:
copy_student_dict的内存地址为:1962128181144,其内容为{‘name’: ‘小明’}
copy_student_dict的内存地址为:1962128181144,其内容为{‘name’: ‘Commas’}
copy_student_dict的内存地址为:1962128181144,其内容为{‘name’: ‘Commas’}

名称 操作 原字典id值 复制字典id值 说明
浅复制 copy() 1962128181144 1962127493592 不共享内存,所以修改一个字典的值,另外一个字典的值不会修改
深复制 = 1962128181144 1962128181144 共享内存(实质上是两个不同的标识符指向了同一个内存地址),所以修改一个字典的值,另外一个字典的值也会修改
  1. fromkeys(seq[,value])
    Create a new dictionary with keys from iterable and values set to value.
    创建一个新字典,以序列 seq 中元素做字典的键,val 为字典所有键对应的初始值
# name_tuple、name_list均是序列数据结构
name_tuple = ("星爷", "达叔", "Commas")
name_list = ["星爷", "达叔", "Commas"]
# (1)fromkeys(seq)
new_dict = dict.fromkeys(name_tuple)
print(new_dict)
# (2)fromkeys(seq,value)
new_dict.clear() # 清空字典
new_dict = dict.fromkeys(name_list, 100)
print(new_dict)
# 控制台输出:
# {'星爷': None, '达叔': None, 'Commas': None}
# {'星爷': 100, '达叔': 100, 'Commas': 100}

知识加油站:
Python3中有6个序列的内置类型,分别为列表、元组、字符串、Unicode字符串、buffer对象、range对象(Python2的是xrange对象)。

  1. get(key[,default])
    Return the value for key if key is in the dictionary, else default.
    返回指定键的值,如果值不在字典中返回default值
score_dict = {'语文': 98, '英语': 99}
print('{}得了{}分'.format('语文', score_dict.get('语文'), 100))
print('{}得了{}分'.format('英语', score_dict.get('英语')))
print('{}得了{}分'.format('数学', score_dict.get('数学', 100)))
print('{}得了{}分'.format('物理', score_dict.get('物理')))
print('字典现在为{}'.format(score_dict))
# 控制台输出:
# 语文得了98分
# 英语得了99分
# 数学得了100分
# 物理得了None分
# 字典现在为{'语文': 98, '英语': 99}
  1. setdefault(key[,default])
    Insert key with a value of default if key is not in the dictionary.
    Return the value for key if key is in the dictionary, else default.
    返回指定键的值,如果值不在字典中返回default值,并且将此键值更新到原字典。
score_dict = {'语文': 98, '英语': 99}
print('{}得了{}分'.format('语文', score_dict.setdefault('语文'), 100))
print('{}得了{}分'.format('英语', score_dict.setdefault('英语')))
print('{}得了{}分'.format('数学', score_dict.setdefault('数学', 100)))
print('{}得了{}分'.format('物理', score_dict.setdefault('物理')))
print('字典现在为{}'.format(score_dict))
# 控制台输出:
# 语文得了98分
# 英语得了99分
# 数学得了100分
# 物理得了None分
# 字典现在为{'语文': 98, '英语': 99, '数学': 100, '物理': None}
  1. pop(key[,default])
    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
    返回指定键的值,并且删除该键,如果值不在字典中,那么:
    1、有default值,则返回default值;
    2、无default值,则抛出KeyError异常。
score_dict = {'Math': 100, 'English': 97}
print('{}得了{}分'.format('Math', score_dict.pop('Math')))
print('{}得了{}分'.format('Physics', score_dict.pop('Physics', 100)))
print('字典现在为{}'.format(score_dict))

# 下面这一句会抛出KeyError异常
# print('{}得了{}分'.format('Chemistry', score_dict.pop('Chemistry')))

# 控制台输出:
# Math得了100分
# Physics得了100分
# 字典现在为{'English': 97}
  1. popitem()
    D.popitem() -> (k, v), remove and return some (key, value) pair as a
    2-tuple; but raise KeyError if D is empty.
    移除最后一个键值对,并且以元组形式返回被移除的键值对;若字典为空,则会抛出KeyError异常。
score_dict = {'Math': 100, 'English': 97}
popitem_tuple = score_dict.popitem()
print("移除并返回的元组:{}".format(popitem_tuple))
print('字典现在为{}'.format(score_dict))
# 控制台输出:
# 移除并返回一个元组:('English', 97)
# 字典现在为{'Math': 100}
  1. update(dict)
    D.update([E, ]**F) -> None. Update D from dict/iterable E and F.
    If E is present and has a .keys() method, then does: for k in E: D[k] = E[k]
    If E is present and lacks a .keys() method, then does: for k, v in E: D[k] = v
    In either case, this is followed by: for k in F: D[k] = F[k]
    把字典dict的键值对全部更新到原字典(调用该方法的字典)中,
    如果键不存在,就追加键值对到原字典;
    如果键存在,就更新原字典该键的值。
score_dict = {'语文': 98, '数学': 100}
new_dict = {'英语': 99, '数学': 88}
print('原字典:%s' % new_dict)
new_dict.update(score_dict)
print('新字典:%s' % new_dict)
# 控制台输出:
# 原字典:{'英语': 99, '数学': 88}
# 新字典:{'英语': 99, '数学': 100, '语文': 98}
  1. items()、keys()、values()

这三个方法有些特殊,至于为什么特殊?主要体现在方法的返回值上,详情如下表:

方法 数据类型 返回值 说明
items() <class ‘dict_items’> a set-like object 可迭代的,长得像集合的对象
keys() <class ‘dict_keys’> a set-like object 可迭代的,长得像集合的对象
values() <class ‘dict_values’> an object 可迭代的对象

D.items() -> a set-like object providing a view on D’s items
D.keys() -> a set-like object providing a view on D’s keys
D.values() -> an object providing a view on D’s values

(1)看一看方法的返回值是什么?

score_dict = {'语文': 97, '数学': 100, '英语': 99}
items_dict = score_dict.items()
keys_dict = score_dict.keys()
values_dict = score_dict.values()

temp_str = '数据类型是{},数据为 {}'
print_items = temp_str.format(type(items_dict), items_dict)
print_keys = temp_str.format(type(keys_dict), keys_dict)
print_values = temp_str.format(type(values_dict), values_dict)

print(print_items)
print(print_keys)
print(print_values)
# 控制台输出:
# 数据类型是<class 'dict_items'>,数据为 dict_items([('语文', 97), ('数学', 100), ('英语', 99)])
# 数据类型是<class 'dict_keys'>,数据为 dict_keys(['语文', '数学', '英语'])
# 数据类型是<class 'dict_values'>,数据为 dict_values([97, 100, 99])

(2)瞧一瞧返回值(对象)有哪些方法?

score_dict = {'语文': 97, '数学': 100, '英语': 99}

items_dict = score_dict.items()
keys_dict = score_dict.keys()
values_dict = score_dict.values()

print(dir(items_dict))
print(dir(keys_dict))
print(dir(values_dict))
# 控制台输出:
# ['__and__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__or__', '__rand__', '__reduce__', '__reduce_ex__', '__repr__', '__ror__', '__rsub__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__xor__', 'isdisjoint']
# ['__and__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__or__', '__rand__', '__reduce__', '__reduce_ex__', '__repr__', '__ror__', '__rsub__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__xor__', 'isdisjoint']
# ['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']

(i)从控制台输出的结果中可以看出:
1、三个对象的方法中都有__ iter __方法,所以三个对象均可以迭代;
2、三个对象中,只有前两个对象均有一个相同的公有方法isdisjoint(),这个方法是集合所特有的方法,但是这两个对象又不是集合,所以称这两个对象是长得像集合的对象。
(ii)知识加油站
isdisjoint():判断两个集合是否包含相同的元素,如果没有返回 True,否则返回 False。【点击这里可以了解详细使用】

(3)测一测返回值(对象)可否用索引?

score_dict = {'Chinese': 97, 'Math': 100, 'English': 99}
items_dict = score_dict.items()
keys_dict = score_dict.keys()
values_dict = score_dict.values()

try:
    print(items_dict[0])
except Exception as e:
    print(e)

try:
    print(keys_dict[0])
except Exception as e:
    print(e)

try:
    print(values_dict[0])
except Exception as e:
    print(e)

# 控制台输出:
# 'dict_items' object does not support indexing
# 'dict_keys' object does not support indexing
# 'dict_values' object does not support indexing

(i)知识加油站:
上面代码用到了异常捕获的知识,详细教程可以看我写的另外一篇原创博客《Python3之错误和异常浅谈》
(ii)小结:
控制台输出的结果均是不支持索引(index),所以Python并不像其他语言一样,得到的是列表对象,而是一种特殊的对象。

(4)试一试遍历这三个返回值(对象)

score_dict = {'语文': 97, '数学': 100, '英语': 99}

#(1)遍历items()--->元组
items_dict = score_dict.items()
temp_str = '元组值为{},其元素分别为{}、{}'
for item in items_dict:
    print_str = temp_str.format(item, item[0], item[1])
    print(print_str)
# 控制台输出:
# 元组值为('语文', 97),其元素分别为语文、97
# 元组值为('数学', 100),其元素分别为数学、100
# 元组值为('英语', 99),其元素分别为英语、99

#(1)遍历items()--->key:value
temp_str = 'key值为{},value值为{}'
for k, v in items_dict:
    print_str = temp_str.format(k, v)
    print(print_str)
# 控制台输出:
# key值为语文,value值为97
# key值为数学,value值为100
# key值为英语,value值为99

#(2)遍历keys()
keys_dict = score_dict.keys()
temp_str = 'key值为{}'
for key in keys_dict:
    print_str = temp_str.format(key)
    print(print_str)
# 控制台输出:
# key值为语文
# key值为数学
# key值为英语

#(3)遍历values()
values_dict = score_dict.values()
temp_str = 'value值为{}'
for value in values_dict:
    print_str = temp_str.format(value)
    print(print_str)
# 控制台输出:
# value值为97
# value值为100
# value值为99

三、字典的遍历

需要指出的是,字典的遍历,返回的是键值,并不能返回键值对,如需返回键值对,可以参考字典的item()方法,请看上文,有所介绍。

  1. 正确遍历字典的示例
score_dict = {'语文': 97, '数学': 100, '英语': 99}
for key in score_dict:
    print(key, score_dict.get(key))
# 控制台输出:
# 语文 97
# 数学 100
# 英语 99
  1. 错误遍历字典的示例
score_dict = {'语文': 99, '数学': 100, '英语': 98}
temp_str = 'key值为“{}”,value值为“{}”'
for key, value in score_dict:
    print(temp_str.format(key, value))
# 控制台输出:
# key值为“语”,value值为“文”
# key值为“数”,value值为“学”
# key值为“英”,value值为“语” 

本文参考:
1、https://www.runoob.com/python/python-dictionary.html


版权声明:本文为博主原创文章,如需转载,请给出:
原文链接:https://blog.csdn.net/qq_35844043/article/details/103235952

发布了26 篇原创文章 · 获赞 18 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/qq_35844043/article/details/103235952
今日推荐