3.4 Python 字典类型常用操作及内置方法

发布于:2022-11-13 ⋅ 阅读:(654) ⋅ 点赞:(0)

2022-11-13_01498

1. Dict 字典

1.1 字典

特征: 大括号括起来, 可以存放多个元素, 元素之间用逗号隔开, 元素为 K:V 键值对形式.
Key: , 也成为关键字, 是对v的描述信息, 必须使用不可变类型, 在同一个字典中, 键不可以重复.
Value: 真正的数据, 可以是任意类型.

结构: 变量 = {key: value}
dict1 = {'name': 'kid', 'age': 18, 'hobby': '学习'}

print(dict1)  # {'name': 'kid', 'age': 18, 'hobby': '学习'}
print(type(dict1))  # <class 'dict'>

# 多行书写
dict2 = {
    # 键为字符串
    'name1': 'monkey',
    # 键为整型
    1: 'cat',
    # 键为浮点型
    2.0: 'tiger'
}

print(dict2)  # {'name1': 'monkey', 1: 'cat', 2.0: 'tiger'}

# 键冲突 (Pycharm 提示 字典包含重复键 'k1')
dict3 = {'k1': 'v1', 'k1': 'v2'}
print(dict3)  # {'k1': 'v2'}  # {'k1': 'v2'}

1.2 获取元素

1. 字典[key]取值
字典是一种映射类型(mapping type), 是一个无序的键:值对集合,
无法通过索引来取值, 而是通过 Key 来取值.

格式: 变量[key]
嵌套取值: 变量[key][key]···
dict1 = {'name': 'kid', 'age': 18, 'hobby': {'白天': '学习'}}

print(dict1['name'])  # kid
print(dict1['hobby']['白天'])  # 学习

2. get 方法取值
通过中括号访问时, 键不存在直接报错: KeyError: 'xx'.

.get('键名称', '键不存在返回的信息') 方法: 通过字典key获取字典的value值.
两种种返回的结果: 
* 1. 键存在返回值
* 2. 键不存在, 返回提示信息, 默认为None, 可以自定义返回指定的内容.
dict1 = {'name1': 'monkey', 'name2': 'cat', 'name3': 'tiger'}
print(dict1['name1'])
print(dict1['age'])  # KeyError: 'age'

dict1 = {'name1': 'monkey', 'name2': 'cat', 'name3': 'tiger'}
# 键不存在默认返回None
print(dict1.get('age'))  # None

# 自定义键不存在返回信息
print(dict1.get('age', '访问的键不存在.'))  # 访问的键不存在

1.3 修改元素

不能修改键, 只能修改值, 选中key, 替换value.
格式: 变量[key] = value
dict1 = {'name': 'qz'}
print(dict1)  # {'name': 'qz'}

dict1['name'] = 'kid'
print(dict1)  # {'name': 'kid'}

1.4 版本差异

Python 3.5版本之前的存储是无序的, 3.5版本之后数据存储是有序的.
* 数据存储是无序, 那么意味着输出的顺序是无序的.

image-20221031085132737

2. 构造字典方式

2.1 dict 函数

dict() 函数: 构建字典.
* 1. 使用关键字参数 name=value 初始化的新字典, name参数命的命名规则与变量一样, 参数名会转为字符串.
* 2. 创建空字典, 遍历迭代器对象的值, 使用字典[key]=value, 完成字典的.
# 关键字参数会被 **kwargs 接收
dict1 = dict(k1='v1', k2='v2', k3='v3')
print(dict1)  # {'k1': 'v1', 'k2': 'v2', 'k3': 'v3'}


# 定义一个函数
def a(**kwargs):
    return kwargs


dict2 = a(k1='v1', k2='v2', k3='v3')
print(dict2)  # {'k1': 'v1', 'k2': 'v2', 'k3': 'v3'}

# dict() 内部实现原理
# 定义一个可迭代对象
iterable = [['k1', 'v1'], ['k2', 'v2'], ['k3', 'v3']]

# 定义一个空字典
d = {}

# 遍历迭代器构造字典
for k, v in iterable:
    d[k] = v
    
print(d) # {'k1': 'v1', 'k2': 'v2', 'k3': 'v3'}

# 另一种写法
d = {}  # 创建空字典
for i in list1:
    d[i[0]] = i[1]  # d{k1=v1} == {'k1': 'v1'}

print(d)  # {'k1': 'v1', 'k2': 'v2', 'k3': 'v3'}

2.2 formkeys方法

.formkeys(key, value) 方法: 快速构造字典, 字典所有键指向一个value值,
设置值得时候不要设置可变类型!.
# 列表的元素被作为键
x = ['a', 'b', 'c']  

# 统一添加值为1
list_1 = dict.fromkeys(x, 1)  
print(list_1)

# 列表的元素被作为键
x = ['a', 'b', 'c']

# 如果为[]列表的话, 所有的键都指向同一个内存地址.
list1 = dict.fromkeys(x, [])
print(list1)  # {'a': [], 'b': [], 'c': []}

#  等号赋值是重新指向一个新分空间.
list1['a'] = 1

print(list1)  # {'a': 1, 'b': [], 'c': []}

# 列表的表项被作为键
x = ['a', 'b', 'c']
# 如果为[]列表的话, 所有的键都指向同一个内存地址.
list_1 = dict.fromkeys(x, [])

# 内部复制与链式赋值一样, 后一个变量指向前一个变量指向的值.
print(list_1)

list_1['a'].append(1)  # {'a': [1], 'b': [1], 'c': [1]}
print(list_1)

3. 获取键值

3.1 获取所有键

.values() 方法: 将字典中的所有值组成一个可迭代序列(dict_values对象)并返回.
dict1 = {'name': 'kid', 'age': 18, 'hobby': ['read', 'eat']}

keys = dict1.keys()
# 查看所有键
print(keys, type(keys))  
# dict_keys(['name', 'age', 'hobby']) <class 'dict_keys'>

3.2 获取所有值

.values() 方法: 将字典中的所有值组成一个可迭代序列(dict_values对象)并返回.
dict1 = {'name': 'kid', 'age': 18, 'hobby': ['read', 'eat']}

values = dict1.values()

# 查看所有值
print(values, type(values))  
# dict_values(['kid', 18, ['read', 'eat']]) <class 'dict_values'>

3.3 获取所有键值对

.items()  方法: 将字典中的所有键值对组成一个可迭代序列(dict_items对象)并返回.
dict1 = {'name': 'kid', 'age': 18, 'hobby': ['read', 'eat']}

items = dict1.items()
# 查看所有键值对
print(items)
# dict_items([('name', 'kid'), ('age', 18), ('hobby', ['read', 'eat'])])

print(type(items))
# <class 'dict_items'>

3.4 版本差异

Python3 中返回可迭代对象, 使用for遍历取值, 可以使用 list() 转换成列表.
Python2 中返回真正的列表.
# Python3
dict1 = {'name': 'kid', 'age': 18, 'hobby': ['read', 'eat']}

values = dict1.values()
print(values)
# dict_values(['kid', 18, ['read', 'eat']])

# 迭代器转为列表
print(list(values))
# ['kid', 18, ['read', 'eat']]

# 遍历迭代器取值
for i in values:
    print(i)
    
运行工具窗口显示:
kid
18
['read', 'eat']
# Python2 
dict1 = {'name': 'kid', 'age': 18, 'hobby': ['read', 'eat']}
print(dict1.keys())
# ['hobby', 'age', 'name']

print(dict1.values())
# [['read', 'eat'], 18, 'kid']

print(dict1.items())
# [('hobby', ['read', 'eat']), ('age', 18), ('name', 'kid')]

4. 元素统计

len() 统计字典中字典中键值对的个数.
dic1 = {'k1': 'v1', 'k2': 'v2'}
print(len(dic1))  # 2

5. 成员运算

in  not in : 判断某个值是否在某个群体中, 返回值为布尔值.
字典中只默认提供key的访问, value不会暴露.
可是使用.values()  .items() 将value值展示后做判断.
dict1 = {
    'name1': 'monkey',
    'name2': 'cat',
    'name3': 'tiger'
}

# 判断键 name1 在dict字典中
print('name1' in dict1)  # True
# 判断键 aaa 不在dict字典中
print('aaa' not in dict1)  # True

# 尝试访问值是否在字典中
print('monkey' in dict1)  # False
# 通过 .values方法 得到所有值
print('monkey' in dict1.values())  # True

print(dict1.items())
# dict_items([('name1', 'monkey'), ('name2', 'cat'), ('name3', 'tiger')])

# items() 先看成是列表套元组
for items in dict1.items():
    if 'monkey' in items:
        print('monkey' in items)
        

6. 设置默认值

.setdefault('键名', '值') 方法: 为字典的键设置一个默认值. 
* 1. 只写键, 键不存在返回None, 键存则返回键对应的值.
* 2. 键值一起写, 键存在的什么都不做, 键不存则在字典中添加.
dict1 = {'k1': 'v1', 'k2': 'v2', 'k3': 'v3'}

# 先增键值, 键存在什么都不做
dict1.setdefault('k3', 'v2')
print(dict1)
# {'k1': 'v1', 'k2': 'v2', 'k3': 'v3'}

# 先增键值
dict1.setdefault('k4', 'v4')
print(dict1)
# {'k1': 'v1', 'k2': 'v2', 'k3': 'v3', 'k4': 'v4'}

# 查询值, 存在则返回值
print(dict1.setdefault('k4'))  # v4

# 不存在返回None
print(dict1.setdefault('k5', )) 

7. 更新字典

.update({k:v}) 方法: 键不存在则新建, 存在则修改.
dict1 = {'k1': 'v1', 'k2': 'v2', 'k3': 'v3'}
# 键不存在则新增
dict1.update({'k4': 'V4'})
print(dict1)
# {'k1': 'v1', 'k2': 'v2', 'k3': 'v3', 'k4': 'v4'}

# 键存在则修该值
dict1.update({'k1': '6'})
print(dict1)
# {'k1': '6', 'k2': 'v2', 'k3': 'v3', 'k4': 'V4'}

 update 将字典 b 更新字典 a , 会有两种情况: 
* 1. 有相同的键时: 会使用最新的字典 b  key 对应的 value .
* 2. 有新的键时:   会直接把字典 b 中的 key, value 加入到 a .
a = {'k1': 'v1', 'k2': 'v2'}
b = {'k3': 'v3', 'k4': 'v4'}
a.update(b)

print(a)  
# {'k1': 'v1', 'k2': 'v2', 'k3': 'v3', 'k4': 'v4'}

8. 字典合并

方式1: dict(字典1, **字典2)
方式2: 字典1 | 字典2  ,  Python 3.9中更新.
# 字典合并
d1 = {"k1": 1, "k2": 2}
d2 = {"k2": 22, "k3": 33}

dict2 = dict(d1, **d2)

print(dict2)  # {'k1': 1, 'k2': 22, 'k3': 33}

# Python 3.9
d3 = {"k1": 1, "k2": 2}
d4 = {"k2": 22, "k3": 33}

dict3 = d1 | d2

print(dict3)  # {'k1': 1, 'k2': 22, 'k3': 33}

9. 删除元素

9.1 del 关键字

del 关键字 删除指定元素.
dict1 = {
    'name1': 'monkey',
    'name2': 'cat',
    'name3': 'tiger'
}

# 删除dict1字典中 name1键对值
del dict1['name1']

print(dict1)  # {'name2': 'cat', 'name3': 'tiger'}

9.2 弹出元素

.pop() 方法: 弹出键值对, 必须括号内写键的名称, 返回值是弹出的值.
(在字典中这个方法不提供索引, 不要与列表混淆.)
dict1 = {
    'name1': 'monkey',
    'name2': 'cat',
    'name3': 'tiger'
}

# 弹出 第一组值, 弹出值对可以使用变量接收
t1 = dict1.pop('name1')
print(t1)  # monkey

print(dict1)  # {'name2': 'cat', 'name3': 'tiger'}

9.3 随机弹出

.popitem() 方法: 随机弹出一组键值, 返回值是一个元组(, ).
* Python 3.5 后是有序字典, 从末尾弹出.
dict1 = {
    'name1': 'monkey',
    'name2': 'cat',
    'name3': 'tiger'
}

# 弹出最后一组键值对
t3 = dict1.popitem()
print(t3)  # ('name3', 'tiger')

# 弹出最后一组键值对
t2 = dict1.popitem()
print(t2)  # ('name2', 'cat')

print(dict1)  # {'name1': 'monkey'}

9.4 清空字典

.clear()方法: 清空字典.
dict1 = {
    'name1': 'monkey',
    'name2': 'cat',
    'name3': 'tiger'
}

# 清空字典
dict1.clear()
print(dict1)  # {}

10. 遍历字典

for 循环 遍历字典得到的只有键.
dic1 = {'name': 'kid', 'age': 18, 'hobby': ['read', 'eat']}
# 默认只能拿到键
for k in dic1.keys():
    print(k)

# 获取值
for v in dic1.values():
    print(v)
    
运行工具窗口显示:
name
age
hobby
kid
18
['read', 'eat']
dic1 = {'name': 'kid', 'age': 18, 'hobby': ['read', 'eat']}

# 列表套元组
print(dic1.items())
# dict_items([('name', 'kid'), ('age', 18), ('hobby', ['read', 'eat'])])

# 获取元组
for item in dic1.items():
    print(item)

# 遍历的元组值分类分给k和v
for x, y in dic1.items():
    print(x, y)

运行工具窗口显示:
('name', 'kid')
('age', 18)
('hobby', ['read', 'eat'])
name kid
age 18
hobby ['read', 'eat']

11. 练习

1.统计字符的个数以字典的形式显示.
# 统计字符的个数以字典的形式显示.
str1 = "asdfmaslsopdfjosdjfjsdfogjsdgsadjfaojfiajsdfoihaiwehrqowfjskdnfarwhfjkklnwaoiejfo;asfnasCmskdvn"

# 1.新建空字典
d1 = {}
# 2. 遍历字符串
for i in str1:
    d1[i] = str1.count(i)

print(d1)

# 1.新建空字典
d1 = {}
# 2. 遍历字符串
for i in str1:
    # 判断字符是否在字典中
    if i not in d1:
        # 不存在则新增
        d1[i] = 0

    # 存在则计数 + 1
    d1[i] += 1

print(d1)

# 2.有如下值集合 [11,22,33,44,55,67,77,88,99,90], 
# 将所有大于 66 的值保存至字典的第一个key中, 将小于 66 的值保存至第二个key的值中.
# 即: {'k1': 大于66的所有值, 'k2': 小于66的所有值}

l1 = [11, 22, 33, 44, 55, 67, 77, 88, 99, 90]

# 1. 创建空字典
d1 = {'k1': [], 'k2': []}

for i in l1:
    if i > 66:
        d1['k1'].append(i)
    else:
        d1['k2'].append(i)

print(d1)
# 3.统计s='hello word word xx hello xx xx'中每个单词的个数
# 即: {'hello': hello的个数, ...}

s = 'hello word word xx hello xx xx'
list1 = s.split()
dic = {}
print(list1)
for i in list1:
    if i not in dic:
        dic[i] = list1.count(i)

print(dic)
4.简单购物车, 要求如下:
实现打印商品详细信息, 用户输入商品名和购买个数, 则将商品名, 价格, 
购买个数以列表形式{'商品名': [价格, 购买个数], ...}数加入购物列表, 
如果输入为空或其他非法输入则要求用户重新输入(只能输入纯数字字符和字母q),按下q退出并打印购物列表.
shop_dic = {
    '苹果': 5.6,
    '香蕉': 4.8,
    '西瓜': 3.5,
    '葡萄': 8.9,
    '桃子': 5.0,
}
shop_dic = {
    '苹果': 5.6,
    '香蕉': 4.8,
    '西瓜': 3.5,
    '葡萄': 8.9,
    '桃子': 5.0,
}
# 打印信息
for k, v in shop_dic.items():
    print(f'{k} 价格 {v}')

# 创建一个购物车字典
shop_cat = {}
while True:
    fruits = input('输入水果的名字>>>:').strip()
    # 判断输入的名字是否存在字典中,不存在就输入错了
    if fruits not in shop_dic:
        print('输入的水果不存在!')
    else:
        # 水果存在就输入数量
        num = input('请输入购买的数量>>>:').strip()
        # 纯数字判断
        if num.isdigit():
            # 判断是否已经添加到购物车了
            if fruits in shop_cat:
                # 添加过修改数量
                shop_cat[fruits][1] += int(num)
            else:
                # 没添加就组织格式
                list_msg = [shop_dic[fruits], int(num)]
                # 添加到购物车
                shop_cat[fruits] = list_msg
        else:
            print('输入的数量格式不正确!')
        print(shop_cat)
    if input('按下q退出购物,否则继续>>>:').strip() == 'q':
        break
5. 在无法确定 key 是否存在的情况下, 如何从字典中取值才能保持程序不会出错.
6. 简述 Python3  dict.keys(), dict.values(), dict.items() 包含的内容及与 Python2 的区别.
7. 字典键不存在有几种方法创建一堆键值.

文章的段落全是代码块包裹的, 留言0是为了避免文章提示质量低.
文章的段落全是代码块包裹的, 留言1是为了避免文章提示质量低.
文章的段落全是代码块包裹的, 留言2是为了避免文章提示质量低.
文章的段落全是代码块包裹的, 留言3是为了避免文章提示质量低.
文章的段落全是代码块包裹的, 留言4是为了避免文章提示质量低.
文章的段落全是代码块包裹的, 留言5是为了避免文章提示质量低.
文章的段落全是代码块包裹的, 留言6是为了避免文章提示质量低.
文章的段落全是代码块包裹的, 留言7是为了避免文章提示质量低.
文章的段落全是代码块包裹的, 留言8是为了避免文章提示质量低.
文章的段落全是代码块包裹的, 留言9是为了避免文章提示质量低.



网站公告

今日签到

点亮在社区的每一天
去签到