迄今为止,我们已经为大家介绍了Python中的三种容器型数据类型,但是这些数据类型还不足以帮助我们解决所有的问题。例如,我们要保存一个人的信息,包括姓名、年龄、体重、单位地址、家庭住址、本人手机号、紧急联系人手机号等信息,你会发现我们之前学过的列表、元组和集合都不是最理想的选择。

person1 = ['王大锤', 55, 60, '科华北路62号', '中同仁路8号', '13122334455', '13800998877']

person2 = ('王大锤', 55, 60, '科华北路62号', '中同仁路8号', '13122334455', '13800998877')

person3 = {'王大锤', 55, 60, '科华北路62号', '中同仁路8号', '13122334455', '13800998877'}

集合肯定是最不合适的,因为集合有去重特性,如果一个人的年龄和体重相同,那么集合中就会少一项信息;同理,如果这个人的家庭住址和单位地址是相同的,那么集合中又会少一项信息。另一方面,虽然列表和元组可以把一个人的所有信息都保存下来,但是当你想要获取这个人的手机号时,你得先知道他的手机号是列表或元组中的第6个还是第7个元素;当你想获取一个人的家庭住址时,你还得知道家庭住址是列表或元组中的第几项。总之,在遇到上述的场景时,列表、元组、字典都不是最合适的选择,我们还需字典(dictionary)类型,这种数据类型最适合把相关联的信息组装到一起,并且可以帮助我们解决程序中为真实事物建模的问题。

Python程序中的字典跟现实生活中的字典很像,它以键值对(键和值的组合)的方式把数据组织到一起,我们可以通过键找到与之对应的值并进行操作。就像《新华字典》中,每个字(键)都有与它对应的解释(值)一样,每个字和它的解释合在一起就是字典中的一个条目,而字典中通常包含了很多个这样的条目。

创建和使用字典

在Python中创建字典可以使用{}字面量语法,这一点跟上一节课讲的集合是一样的。但是字典的{}中的元素是以键值对的形式存在的,每个元素由:分隔的两个值构成,:前面是键,:后面是值,代码如下所示。

xinhua = {

'麓': '山脚下', '路': '道,往来通行的地方;方面,地区:南~货,外~货;种类:他俩是一~人',

'蕗': '甘草的别名', '潞': '潞水,水名,即今山西省的浊漳河;潞江,水名,即云南省的怒江'

}

print(xinhua)

person = {

'name': '王大锤', 'age': 55, 'weight': 60, 'office': '科华北路62号',

'home': '中同仁路8号', 'tel': '13122334455', 'econtact': '13800998877'

}

print(person)

通过上面的代码,相信大家已经看出来了,用字典来保存一个人的信息远远优于使用列表或元组,因为我们可以用:前面的键来表示条目的含义,而:后面就是这个条目所对应的值。

当然,如果愿意,我们也可以使用内置函数dict或者是字典的生成式语法来创建字典,代码如下所示。

# dict函数(构造器)中的每一组参数就是字典中的一组键值对

person = dict(name='王大锤', age=55, weight=60, home='中同仁路8号')

print(person)    # {'name': '王大锤', 'age': 55, 'weight': 60, 'home': '中同仁路8'}

# 可以通过Python内置函数zip压缩两个序列并创建字典

items1 = dict(zip('ABCDE', '12345'))

print(items1)    # {'A': '1', 'B': '2', 'C': '3', 'D': '4', 'E': '5'}

items2 = dict(zip('ABCDE', range(1, 10)))

print(items2)    # {'A': 1, 'B': 2, 'C': 3, 'D': 4, 'E': 5}

# 用字典生成式语法创建字典

items3 = {x: x ** 3 for x in range(1, 6)}

print(items3)     # {1: 1, 2: 8, 3: 27, 4: 64, 5: 125}

想知道字典中一共有多少组键值对,仍然是使用len函数;如果想对字典进行遍历,可以用for循环,但是需要注意,for循环只是对字典的键进行了遍历,不过没关系,在讲完字典的运算后,我们可以通过字典的键获取到和这个键对应的值。

person = {'name': '王大锤', 'age': 55, 'weight': 60, 'office': '科华北路62号'}

print(len(person))    # 4

for key in person:

print(key)

字典的运算

对于字典类型来说,成员运算和索引运算肯定是最为重要的,前者可以判定指定的键在不在字典中,后者可以通过键获取对应的值或者向字典中加入新的键值对。值得注意的是,字典的索引不同于列表的索引,列表中的元素因为有属于自己有序号,所以列表的索引是一个整数;字典中因为保存的是键值对,所以字典的索引是键值对中的键,通过索引操作可以修改原来的值或者向字典中存入新的键值对。需要特别提醒大家注意的是,字典中的键必须是不可变类型,例如整数(int)、浮点数(float)、字符串(str)、元组(tuple)等类型的值;显然,列表(list)和集合(set)是不能作为字典中的键的,当然字典类型本身也不能再作为字典中的键,因为字典也是可变类型,但是字典可以作为字典中的值。关于可变类型不能作为字典中的键的原因,我们在后面的课程中再为大家详细说明。这里,我们先看看下面的代码,了解一下字典的成员运算和索引运算。

person = {'name': '王大锤', 'age': 55, 'weight': 60, 'office': '科华北路62号'}

# 检查nametel两个键在不在person字典中

print('name' in person, 'tel' in person)    # True False

# 通过age修将person字典中对应的值修改为25

if 'age' in person:

person['age'] = 25

# 通过索引操作向person字典中存入新的键值对

person['tel'] = '13122334455'

person['signature'] = '你的男朋友是一个盖世垃圾,他会踏着五彩祥云去赢取你的闺蜜'

print('name' in person, 'tel' in person)    # True True

# 检查person字典中键值对的数量

print(len(person))    # 6

# 对字典的键进行循环并通索引运算获取键对应的值

for key in person:

print(f'{key}: {person[key]}')

需要注意,在通过索引运算获取字典中的值时,如指定的键没有在字典中,将会引发KeyError异常。

字典的方法

字典类型的方法基本上都跟字典的键值对操作相关,可以通过下面的例子来了解这些方法的使用。例如,我们要用一个字典来保存学生的信息,我们可以使用学生的学号作为字典中的键,通过学号做索引运算就可以得到对应的学生;我们可以把字典中键对应的值也做成一个字典,这样就可以用多组键值对分别存储学生的姓名、性别、年龄、籍贯等信息,代码如下所示。

# 字典中的值又是一个字典(嵌套的字典)

students = {

1001: {'name': '狄仁杰', 'sex': True, 'age': 22, 'place': '山西大同'},

1002: {'name': '白元芳', 'sex': True, 'age': 23, 'place': '河北保定'},

1003: {'name': '武则天', 'sex': False, 'age': 20, 'place': '四川广元'}

}

# 使用get方法通过键获取对应的值,如果取不到不会引发KeyError异常而是返回None或设定的默认值

print(students.get(1002))    # {'name': '白元芳', 'sex': True, 'age': 23, 'place': '河北保定'}

print(students.get(1005))    # None

print(students.get(1005, {'name': '无名氏'}))    # {'name': '无名氏'}

# 获取字典中所有的键

print(students.keys())      # dict_keys([1001, 1002, 1003])

# 获取字典中所有的值

print(students.values())    # dict_values([{...}, {...}, {...}])

# 获取字典中所有的键值对

print(students.items())     # dict_items([(1001, {...}), (1002, {....}), (1003, {...})])

# 对字典中所有的键值对进行循环遍历

for key, value in students.items():

print(key, '--->', value)

# 使用pop方法通过键删除对应的键值对并返回该值

stu1 = students.pop(1002)

print(stu1)             # {'name': '白元芳', 'sex': True, 'age': 23, 'place': '河北保定'}

print(len(students))    # 2

# stu2 = students.pop(1005)    # KeyError: 1005

stu2 = students.pop(1005, {})

print(stu2)             # {}

# 使用popitem方法删除字典中最后一组键值对并返回对应的二元组

# 如果字典中没有元素,调用该方法将引发KeyError异常

key, value = students.popitem()

print(key, value)    # 1003 {'name': '武则天', 'sex': False, 'age': 20, 'place': '四川广元'}

# setdefault可以更新字典中的键对应的值或向字典中存入新的键值对

# setdefault方法的第一个参数是键,第二个参数是键对应的值

# 如果这个键在字典中存在,更新这个键之后会返回原来与这个键对应的值

# 如果这个键在字典中不存在,方法将返回第二个参数的值,默认为None

result = students.setdefault(1005, {'name': '方启鹤', 'sex': True})

print(result)        # {'name': '方启鹤', 'sex': True}

print(students)      # {1001: {...}, 1005: {...}}

# 使用update更新字典元素,相同的键会用新值覆盖掉旧值,不同的键会添加到字典中

others = {

1005: {'name': '乔峰', 'sex': True, 'age': 32, 'place': '北京大兴'},

1010: {'name': '王语嫣', 'sex': False, 'age': 19},

1008: {'name': '钟灵', 'sex': False}

}

students.update(others)

print(students)      # {1001: {...}, 1005: {...}, 1010: {...}, 1008: {...}}

跟列表一样,从字典中删除元素也可以使用del关键字,在删除元素的时候如果指定的键索引不到对应的值,一样会引发KeyError异常,具体的做法如下所示。

person = {'name': '王大锤', 'age': 25, 'sex': True}

del person['age']

print(person)    # {'name': '王大锤', 'sex': True}

字典的应用

我们通过几个简单的例子来讲解字典的应用。

例子1:输入一段话,统计每个英文字母出现的次数。

sentence = input('请输入一段话: ')

counter = {}

for ch in sentence:

if 'A' <= ch <= 'Z' or 'a' <= ch <= 'z':

counter[ch] = counter.get(ch, 0) + 1

for key, value in counter.items():

print(f'字母{key}出现了{value}次.')

例子2:在一个字典中保存了股票的代码和价格,找出股价大于100元的股票并创建一个新的字典。

说明:可以用字典的生成式语法来创建这个新字典。

stocks = {

'AAPL': 191.88,

'GOOG': 1186.96,

'IBM': 149.24,

'ORCL': 48.44,

'ACN': 166.89,

'FB': 208.09,

'SYMC': 21.29

}

stocks2 = {key: value for key, value in stocks.items() if value > 100}

print(stocks2)

简单的总结

Python程序中的字典跟现实生活中字典非常像,允许我们以键值对的形式保存数据,再通过键索引对应的值。这是一种非常有利于数据检索的数据类型,底层原理我们在后续的课程中再研究。再次提醒大家注意,字典中的键必须是不可变类型,字典中的值可以是任意类型。

温馨提示:大家如果觉得这个专栏还不错,一定记得点赞收藏哟

学Python常用数据结构之字典的更多相关文章

  1. python常用数据结构讲解

    一:序列     在数学上,序列是被排成一排的对象,而在python中,序列是最基本的数据结构.它的主要特征为拥有索引,每个索引的元素是可迭代对象.都可以进行索引,切片,加,乘,检查成员等操作.在py ...

  2. Python常用数据结构-字典——2.1 字典方法 keys()

    python字典常用方法: keys()               #  获取所有的键 values()            #  获取所有的值 items()              #  获 ...

  3. Python常用数据结构之collections模块

    Python数据结构常用模块:collections.heapq.operator.itertools collections collections是日常工作中的重点.高频模块,常用类型由: 计数器 ...

  4. python常用数据结构(1)

    python中有四种最常用的数据结构,分别是列表(list),字典(dict),集合(set)和元组(tuple) 下面简单描述下它们的区别和联系 1.初始化 不得不说,python数据结构的初始化比 ...

  5. Python常用数据结构(列表)

    Python中常用的数据结构有序列(如列表,元组,字符串),映射(如字典)以及集合(set),是主要的三类容器 内容 序列的基本概念 列表的概念和用法 元组的概念和用法 字典的概念和用法 各类型之间的 ...

  6. python核心数据结构之字典

    ![](http://images2015.cnblogs.com/blog/1182370/201706/1182370-20170628210759774-266944364.jpg) [TOC ...

  7. Python常用数据结构之heapq模块

    Python数据结构常用模块:collections.heapq.operator.itertools heapq 堆是一种特殊的树形结构,通常我们所说的堆的数据结构指的是完全二叉树,并且根节点的值小 ...

  8. python 常用数据结构使用

    python 字典操作 http://www.cnblogs.com/kaituorensheng/archive/2013/01/24/2875456.html python 字典排序 http:/ ...

  9. python 常用数据结构

    #coding=utf- #元组,不可变序列(,) a=(,,,) print(a) a=tuple([,,,])#第二种定义方式 print(a) print(a[]) print(a[:]) #可 ...

随机推荐

  1. CSS中link和@import的区别

    1.link属于HTML标签,而@import是CSS提供的 2.页面被加载时link会同时被加载:而@import引用的CSS会等到页面被加载完再加载 3.@import只在IE5以上才能识别,而l ...

  2. ca71a_c++_指向函数的指针_通过指针调用函数txwtech

    /*ca71a_c++_指向函数的指针_通过指针调用函数用typedef简化函数指针的定义简化前: bool(*pf)(const string&, const string &); ...

  3. 【spring】循环依赖 Java Vs Spring

    菜瓜:水稻,这次我特意去看了java的循环依赖 水稻:哟,有什么收获 菜瓜:两种情况,构造器循环依赖,属性循环依赖 构造器循环依赖在逻辑层面无法通过.对象通过构造函数创建时如果需要创建另一个对象,就会 ...

  4. 三文搞懂学会Docker容器技术(下)

    接着上面一篇:三文搞懂学会Docker容器技术(上) 三文搞懂学会Docker容器技术(中) 7,Docker容器目录挂载 7.1 简介 容器目录挂载: 我们可以在创建容器的时候,将宿主机的目录与容器 ...

  5. mysql定时备份任务

    简介 在生产环境上,为了避免数据的丢失,通常情况下都会定时的对数据库进行备份.而Linux的crontab指令则可以帮助我们实现对数据库定时进行备份.首先我们来简单了解crontab指令,如果你会了请 ...

  6. Java集合框架(不全,待继续整理)

    技术在线学习网站: https://www.runoob.com/java/java-collections.html 从上面的集合框架图可以看到: 1.Java 集合框架主要包括两种类型的容器: 1 ...

  7. 恕我直言你可能真的不会java第6篇:Stream性能差?不要人云亦云

    一.粉丝的反馈 问:stream比for循环慢5倍,用这个是为了啥? 答:互联网是一个新闻泛滥的时代,三人成虎,以假乱真的事情时候发生.作为一个技术开发者,要自己去动手去做,不要人云亦云. 的确,这位 ...

  8. 入门大数据---HDFS-HA搭建

    一.简述 上一篇了解了Zookeeper和HDFS的一些概念,今天就带大家从头到尾搭建一下,其中遇到的一些坑也顺便记录下. 1.1 搭建的拓扑图如下: 1.2 部署环境:Centos3.1,java1 ...

  9. WARN deploy.SparkSubmit$$anon$2: Failed to load org.apache.spark.examples.sql.streaming.StructuredNetworkWordCount.

    前言 今天运行Spark Structured Streaming官网的如下 ./bin/run-example org.apache.spark.examples.sql.streaming.Str ...

  10. Spring Boot入门系列(十六)使用pagehelper实现分页功能

    之前讲了Springboot整合Mybatis,然后介绍了如何自动生成pojo实体类.mapper类和对应的mapper.xml 文件,并实现最基本的增删改查功能.接下来要说一说Mybatis 的分页 ...