先给大家抛出两个问题,思考后再请继续阅读后续内容:
- 有两本书,需要你放好,以备后续使用
- 有一千本书,需要你放好,以备后续使用
1. 数据结构初探
遥想当年学数据结构的时候,“数组、链表、栈、队列、散列表、二叉树、堆、跳表、图、树”,那是一个云里雾里,不知所云,如读天书……
摸索实践,摸索实践,终于悟出了点端倪,你在放书时候,书的多少会决定你放书的方式,书很少的时候你可能更多时候会随意摆放(基本数据类型),但书很多的时候你可能会想着要放到一个固定的位置了而且还可能会编个号(数组),书如果再多的话(图书馆里一样多的书)你可能会进一步思考了……
数据结构很重要,但要真真自己考虑如何组织存取数据,我相信这个任务还是很有压力的,好在 小Python 提供了一些基于数据结构的实现方式 —— 内置数据结构类型,我们可以站在 小Python 的肩膀上来完成各种各样的复杂的数据存取操作。但研究数据结构底层实现依然是很重要的,该话题容后再续。
总结:在计算机科学中,数据结构(英语:data structure)是计算机中存储、组织数据的方式。
2. 小Python 的数据结构
在 小Python 的官方描述中,将*列表(List)、元组(Tuple)、字典(Dictionary)和集合(Set)*归为四种内置的数据结构,大多数应用程序都不会用到其他的数据结构,但如果遇到了,小Python 还会为这些将要用到的结构提供一个强大的、经过良好测试的版本。
博主不会先罗列这几种数据类型的具体用法,而是给出几个问题,然后告诉你这几个数据类型的特点,你可以自己选择,这应该更有利于你的思维以及技能的提升。
2.1 问题探究
- 存放 10 本书的信息(书名,作者,价格,ISBN等等)
- 存放《小Python之路》这个本书的信息(书名,作者,价格,ISBN等等)
- 存放 10 本书的名称
这三个小问题,我们如果还是用之前的基本数据类型(整型,浮点型,复数,布尔,字符串)来存取,似乎有些力所不及了,至少操作起来会非常的麻烦。
2.2 概念解读
2.2.1 列表(list)
列表 是一种按照位置编号来摆放数据项的一种数据结构。也就是说,你可以在列表中存储一系列项。这很容易想象,如果你有一系列的东西要买就会思考出一个购物清单,可能在你的购物清单中每一项都有一个单独的行,而在 小Python 中使用逗号隔开它们。
列表 应该使用方括号扩起来,以便 小Python 能够理解你正在定义一个列表。一旦创建了列表,你就可以在列表中增加,删除或者搜索列表中的项 。 正因为我们可以增加和删除项,所以我们称列表是一种 可变 数据类型,也就是说这个类型可以被修改。
支持操作:列表的详细用法
2.2.2 元组(tuple)
元组 用于将多个数据项组合在一起。可以将它们近似看作列表,但是没有列表类提供的许多功能。元组的一个重要特征是,它们和字符串一样是 不可变 数据类型,即你不能修改元组。
元组 是由一些特殊的项定义的,这些项在一对可选的圆括号中,由逗号隔开。
元组 通常用于这种情况,可以安全地认为值的集合(即,值的元组)不会改变的情况。
支持操作:元组的详细用法
2.2.3 字典(dict)
字典 就像是一个地址簿,只要知道一个人的名字,你就可以找到他 / 她的地址或联系方式,即,我们将键 (名字)与 值 (详细信息)相关联。注意,键必须是唯一的!就好比是,如果有两个人重名,那就无法找到正确的详细信息一样。
注意,对于字典的键,你只能使用 不可变 对象(基本数据类型,元组这些),但是对于字典的值,无限制使用。这基本上就意味着,对于字典的键,你最好只使用简单点的数据项来描述。
可以通过 d = {key1 : value1, key2 : value2 } ,就可以指定字典中的键值对。注意,一个键值对中的键与值由冒号隔开,而不同键值对之间是由逗号隔开,所有的键值对以及冒号、逗号都包含在一对花括号中。
记住,字典中的键值对不以任何方式排序(不像列表中的像一样有从小到大递增的索引)。如果你想要得到一个特殊的顺序。那么在使用字典之前,你必须自己对其进行排序。
支持操作:字典的详细用法
2.2.4 集合
集合 源自数学概念,是一个 无序 的 不重复 的数据项集合。常见的用途包括成员检测、从序列中去除重复项以及数学中的集合类计算,例如交集、并集、差集与对称差集等等。集合不支持索引、切片或其他序列类的操作。
可以使用大括号 { } 或者 set() 函数创建集合,注意:创建一个空集合必须用 set() 而不是 { },因为 { } 是用来创建一个空字典。
支持操作:集合的详细用法
2.3 问题连线
现在你应该了解了 小Python 的数据结构能够解决哪些问题了吧。
- 存放 10 本书的名称
- 使用 列表 或者 元组 存取
- 存放《小Python之路》这个本书的信息(书名,作者,价格,ISBN等等)
- 使用 字典 存取
- 存放 10 本书的信息(书名,作者,价格,ISBN等等)
- 使用 字典 存取每本书的信息,使用 列表 存取多本书
下一步,应该是该如何实现呢,这个时候其实你可以探索性的跟着官方文档来学习解决问题,当然也可以看看博主的实现。
3. 问题解决
3.1 问题一
"""
文件名:store_ten_book_name.py
用途:存放 10 本书的名称
作者:Mr.潘
"""
# 列表存取 - 支持数据项的增(存)、删、改、查(取)
books = ["《红楼梦》", "《三国演义》", "《水浒传》", "《西游记》", "《哈姆雷特》", "《奥赛罗》", "《李尔王》", "《麦克白》", "《仲夏夜之梦》", "《威尼斯商》"]
# 取一本书来看看吧
print(books[0])
# 添加两本吧
books.insert(0, "《第十二夜》") # 可通过 print(books) 查看变化
books.append("《皆大欢喜》") # 可通过 print(books) 查看变化
# 删除两本吧
books.remove("《皆大欢喜》") # 可通过 print(books) 查看变化
books.pop() # 可通过 print(books) 查看变化
# 更正个错误项吧
books[9] = "《威尼斯商人》" # 可通过 print(books) 查看变化
# 更多操作,请参见对应官方文档
3.2 问题二
"""
文件名:store_one_book_detail_info.py
用途:存放 《小Python之路》 这个本书的信息(书名,作者,价格,ISBN等等)
作者:Mr.潘
"""
# 字典存取 - 支持数据项的增(存)、删、改、查(取)
book = {"name":"《小Python之路》", "author":"Mr.潘", "price":38.5, "ISBN":"202008131038"}
# 关注下作者看看吧
print(book["author"]) # 等效用法:print(book.get("author"))
# 添加个出版社的信息吧
book["publish"] = "人民教育出版社" # 等效用法:book.setdefault("publish", "人民教育出版社")
# 搞个活动,降降价吧
book["price"] = 33 # 等效用法:book.update("price"=33)
# ISBN 就不需要了吧
del book["ISBN"] # 等效用法:book.pop("ISBN")
# 更多操作,请参见对应官方文档
3.3 问题三
"""
文件名:store_ten_book.py
用途:存放 10 本书的信息(书名,作者,价格,ISBN等等)
作者:Mr.潘
"""
# 字典存取 事物/个体 的多项信息
# book_1 = {"name":"《小Python之路》", "author":"Mr.潘", "price":38.5, "ISBN":"202008131038"}
# ...
# 列表存取 多项数据
# books = [book_1, book_2, book_3, book_4, book_5, book_6, book_7, book_8, book_9, book_10]
## 这么存取太累了,给个灵活的操作吧
BOOK_NUMBER = 10
books = []
# 遍历 10 次循环,重复添加书籍
for i in range(BOOK_NUMBER):
book_name = input("书名:")
book_author = input("作者:")
book_price = float(input("价格:"))
book_ISBN = input("ISBN:")
book = {"name":book_name, "author":book_author, "price":book_price, "ISBN":book_ISBN}
books.append(book)
print(books) # 简单测试一下结果
4. 数据再分类
从应用者的角度考虑,能够方便我们记忆与使用的才是王道。类比,类推,联想,温故知新等等都是基于已有的知识储备,根据相似性去推导另外一种相似事物的特征行为的,就如同:程序员这样一个群体,会写代码,热衷于技术,视电脑为第二夫人,而我是一名程序员,我会写代码,我热衷于技术,我视电脑为第二夫人,😄 ,我也大致可以推导出其他程序员(吉多,张小龙等等,有点攀高了)也会写代码,也热衷于技术,也视电脑为第二夫人或第三夫人……
4.1 数值类型
- 整数类型:
int
,所有整数都具有 数值的通用操作 和int
类型的特有操作 - 浮点数类型:
float
,所有浮点数都具有 数值的通用操作 和float
类型的特有操作 - 复数类型:
complex
,所有复数都具有 数值的通用操作 和complex
类型的特有操作 - 布尔类型:
bool
,属于整数的子类型,所有布尔值都具有 数值的通用操作 和bool
类型的特有操作
4.2 序列类型
- 列表类型:
list
,实现了所有 一般 和 可变 序列的操作,还额外提供了附加方法 - 元组类型:
tuple
,实现了所有 一般 序列的操作 - range类型:
range
,实现了 一般 序列的所有操作,但拼接和重复除外 - 字符串类型:
str
,实现了所有 一般 序列的操作,还额外提供了一些附加方法 - 二进制序列类型:
bytes
、bytearray
,实现了所有 一般 序列的操作,也有其特有操作
4.3 映射类型
- 字典类型:
dict
,只有这一种实现,具体操作,因而自定义的映射类型也应当支持
4.4 集合类型:
在后续的博文中,大家除了使用至今我们接触到的 数据类型 之外,还会学习更多的 数据类型,甚至可以自己去创建新的 数据类型 以满足我们的使用,从一种 数据类型 派生(实例化)出的数据(对象),应该具有该隶属于该 数据类型(类型/类) 所具有的特征(属性)和行为(方法)。