Python 数据结构 - 快速指南


Python-DS简介

在这里,我们将了解什么是Python编程语言的数据结构。

数据结构概述

数据结构是计算机科学的基本概念,有助于用任何语言编写高效的程序。Python 是一种高级、解释性、交互式和面向对象的脚本语言,与其他编程语言相比,我们可以使用它以更简单的方式学习数据结构的基础知识。

在本章中,我们将简要概述一些常用的数据结构,以及它们与某些特定的 Python 数据类型的关系。还有一些特定于Python的数据结构被列为另一类。

通用数据结构

计算机科学中的各种数据结构大致分为如下所示的两类。我们将在后续章节中详细讨论以下每个数据结构。

线性数据结构

这些是以顺序方式存储数据元素的数据结构。

  • 数组- 它是与数据元素的索引配对的数据元素的顺序排列。

  • 链接列表- 每个数据元素都包含到另一个元素的链接以及其中存在的数据。

  • 堆栈- 它是一种仅遵循特定操作顺序的数据结构。LIFO(后进先出)或 FILO(先进后出)。

  • 队列- 与堆栈类似,但操作顺序仅为 FIFO(先进先出)。

  • 矩阵- 它是二维数据结构,其中数据元素由一对索引引用。

非线性数据结构

这些数据结构中没有数据元素的顺序链接。任何一对或一组数据元素都可以相互链接,并且可以在没有严格顺序的情况下进行访问。

  • 二叉树- 它是一种数据结构,其中每个数据元素可以连接到最多两个其他数据元素,并且以根节点开始。

  • - 这是树数据结构的一种特殊情况,其中父节点中的数据要么严格大于/等于子节点,要么严格小于其子节点。

  • 哈希表- 它是一种数据结构,由使用哈希函数相互关联的数组组成。它使用键而不是数据元素中的索引检索值。

  • - 它是顶点和节点的排列,其中一些节点通过链接相互连接。

Python 特定数据结构

这些数据结构是Python语言特有的,它们在存储不同类型的数据时提供了更大的灵活性,并在Python环境中更快地进行处理。

  • 列表- 它与数组类似,但数据元素可以是不同的数据类型。Python 列表中可以同时包含数字和字符串数据。

  • 元组- 元组与列表类似,但它们是不可变的,这意味着元组中的值无法修改,只能读取。

  • 字典- 字典包含键值对作为其数据元素。

在接下来的章节中,我们将详细了解如何使用 Python 实现这些数据结构。

Python-DS 环境

Python 可在多种平台上使用,包括 Linux 和 Mac OS X。让我们了解如何设置 Python 环境。

本地环境设置

打开终端窗口并输入“python”以查明它是否已安装以及安装的版本。

  • Unix(Solaris、Linux、FreeBSD、AIX、HP/UX、SunOS、IRIX 等)
  • 赢得 9x/NT/2000
  • Macintosh(英特尔、PPC、68K)
  • 操作系统/2
  • DOS(多个版本)
  • 掌上操作系统
  • 诺基亚手机
  • WindowsCE
  • 橡子/RISC操作系统
  • 贝奥斯
  • 阿米加
  • 虚拟管理系统/开放虚拟管理系统
  • QNX
  • VxWorks
  • 心灵术士
  • Python 还被移植到 Java 和 .NET 虚拟机

获取Python

最新的、最新的源代码、二进制文件、文档、新闻等,都可以在Python的官方网站www.python.org上找到

您可以从此处提供的网站www.python.org/doc下载 Python 文档。该文档以 HTML、PDF 和 PostScript 格式提供。

安装Python

Python 发行版可用于多种平台。您只需下载适用于您的平台的二进制代码并安装 Python。

如果您的平台的二进制代码不可用,您需要 C 编译器来手动编译源代码。编译源代码在选择安装中所需的功能方面提供了更大的灵活性。

以下是在各种平台上安装 Python 的快速概述 -

Unix 和 Linux 安装

以下是在 Unix/Linux 机器上安装 Python 的简单步骤。

  • 打开 Web 浏览器并访问www.python.org/downloads

  • 点击链接下载适用于 Unix/Linux 的压缩源代码。

  • 下载并解压文件。

  • 如果您想自定义某些选项,请编辑模块/安装文件。

  • 运行./configure脚本

  • 制作

  • 进行安装

这会将 Python 安装在标准位置/usr/local/bin并将其库安装在/usr/local/lib/pythonXX处,其中 XX 是 Python 的版本。

Windows安装

以下是在 Windows 计算机上安装 Python 的步骤。

  • 打开 Web 浏览器并访问www.python.org/downloads

  • 单击 Windows 安装程序python-XYZ.msi文件的链接,其中 XYZ 是您需要安装的版本。

  • 要使用此安装程序python-XYZ.msi,Windows 系统必须支持 Microsoft Installer 2.0。将安装程序文件保存到本地计算机,然后运行它以查明您的计算机是否支持 MSI。

  • 运行下载的文件。这会弹出 Python 安装向导,非常易于使用。只需接受默认设置,等待安装完成即可。

Macintosh 安装

最近的 Mac 都安装了 Python,但它可能已经过时了几年。有关获取当前版本以及支持 Mac 上开发的额外工具的说明,请参阅www.python.org/download/mac/ 。对于 Mac OS X 10.3(2003 年发布)之前的旧版 Mac 操作系统,可以使用 MacPython。

Jack Jansen 维护它,您可以在他的网站上完全访问整个文档 - http://www.cwi.nl/~jack/macpython.html。您可以找到 Mac OS 安装的完整安装详细信息。

设置路径

程序和其他可执行文件可以位于许多目录中,因此操作系统提供了一个搜索路径,其中列出了操作系统搜索可执行文件的目录。

该路径存储在环境变量中,该变量是由操作系统维护的命名字符串。该变量包含命令 shell 和其他程序可用的信息。

路径变量在 Unix 中命名为 PATH,在 Windows 中命名为 Path(Unix 区分大小写;Windows 不区分大小写)

在 Mac OS 中,安装程序处理路径详细信息。要从任何特定目录调用 Python 解释器,您必须将 Python 目录添加到您的路径中。

在 Unix/Linux 下设置路径

将 Python 目录添加到 Unix 中特定会话的路径 -

  • 在 csh shell 中- 输入 setenv PATH "$PATH:/usr/local/bin/python" 并按 Enter。

  • 在 bash shell (Linux) 中- 输入 export ATH="$PATH:/usr/local/bin/python" 并按 Enter。

  • 在 sh 或 ksh shell 中- 输入 PATH="$PATH:/usr/local/bin/python" 并按 Enter。

  • 注意- /usr/local/bin/python 是 Python 目录的路径

在 Windows 下设置路径

将 Python 目录添加到 Windows 中特定会话的路径 -

  • 在命令提示符处- 输入路径 %path%;C:\Python 并按 Enter。

  • 注意- C:\Python 是 Python 目录的路径

Python环境变量

以下是 Python 可以识别的重要环境变量 -

先生。 变量和描述
1

Python路径

它的作用与PATH类似。该变量告诉 Python 解释器在哪里找到导入到程序中的模块文件。它应该包括Python源库目录和包含Python源代码的目录。PYTHONPATH 有时由 Python 安装程序预设。

2

Python启动

它包含包含Python源代码的初始化文件的路径。每次启动解释器时都会执行它。它在 Unix 中名为.pythonrc.py,包含加载实用程序或修改 PYTHONPATH 的命令。

3

蟒蛇卡塞克

它在 Windows 中用于指示 Python 在 import 语句中查找第一个不区分大小写的匹配项。将此变量设置为任意值以激活它。

4

Python之家

它是一个替代模块搜索路径。它通常嵌入在 PYTHONSTARTUP 或 PYTHONPATH 目录中,以便于切换模块库。

运行Python

启动 Python 的方式有以下三种:

互动口译员

  • 您可以从 Unix、DOS 或任何其他为您提供命令行解释器或 shell 窗口的系统启动 Python。

  • 命令行输入python 。

  • 立即在交互式解释器中开始编码。

$python # Unix/Linux
or
python% # Unix/Linux
or
C:> python # Windows/DOS

这是所有可用命令行选项的列表,如下所述 -

先生。 选项和说明
1

-d

它提供调试输出。

2

-O

它生成优化的字节码(生成 .pyo 文件)。

3

-S

不要在启动时运行 import site 来查找 Python 路径。

4

-v

详细输出(导入语句的详细跟踪)。

5

-X

禁用基于类的内置异常(只需使用字符串);从版本 1.6 开始已过时。

6

-c命令

运行作为 cmd 字符串发送的 Python 脚本

7

文件

从给定文件运行 Python 脚本

来自命令行的脚本

可以通过在应用程序上调用解释器来在命令行执行 Python 脚本,如下所示 -

$python script.py # Unix/Linux

or

python% script.py # Unix/Linux

or 

C: >python script.py # Windows/DOS
  • 注意- 确保文件权限模式允许执行。

集成开发环境(IDE)

如果您的系统上有支持 Python 的 GUI 应用程序,您也可以从图形用户界面 (GUI) 环境运行 Python。

  • Unix - IDLE 是第一个用于 Python 的 Unix IDE。

  • Windows - PythonWin 是第一个 Python 的 Windows 界面,是一个带有 GUI 的 IDE。

  • Macintosh - Macintosh 版本的 Python 以及 IDLE IDE 可从主网站获取,可作为 MacBinary 或 BinHex 文件下载。

如果您无法正确设置环境,那么您可以向系统管理员寻求帮助。确保 Python 环境已正确设置并且工作正常。

  • 注意- 后续章节中给出的所有示例均使用 CentOS 风格的 Linux 上可用的 Python 2.4.3 版本执行。

我们已经在线搭建了Python编程环境,以便您在学习理论的同时可以在线执行所有可用的示例。请随意修改任何示例并在线执行。

Python-数组

数组是一个可以容纳固定数量的元素的容器,并且这些元素应该是相同的类型。大多数数据结构都使用数组来实现其算法。以下是理解数组概念的重要术语:

  • 元素- 存储在数组中的每个项目称为元素。

  • 索引- 数组中元素的每个位置都有一个数字索引,用于标识该元素。

数组表示

数组可以用不同的语言以不同的方式声明。下面是一个例子。

数组声明 数组表示

根据上图,以下是需要考虑的要点 -

  • 索引从0开始。

  • 数组长度为10,即可以存储10个元素。

  • 每个元素都可以通过其索引来访问。例如,我们可以将索引 6 处的元素获取为 9。

基本操作

数组支持的基本操作如下所示 -

  • 遍历- 逐一打印所有数组元素。

  • 插入- 在给定索引处添加一个元素。

  • 删除- 删除给定索引处的元素。

  • 搜索- 使用给定索引或值搜索元素。

  • 更新- 更新给定索引处的元素。

通过将 array 模块导入到 python 程序中,在 Python 中创建数组。然后,数组声明如下 -

from array import *

arrayName = array(typecode, [Initializers])

类型代码是用于定义数组将保存的值的类型的代码。使用的一些常见类型代码如下 -

类型代码 价值
表示大小为 1 字节的有符号整数
表示大小为 1 字节的无符号整数
C 表示大小为1字节的字符
表示大小为 2 字节的有符号整数
表示大小为 2 字节的无符号整数
F 表示大小为 4 字节的浮点数
d 表示大小为 8 字节的浮点数

在查看各种数组操作之前,让我们使用 python 创建和打印数组。

例子

以下代码创建一个名为array1的数组。

from array import *

array1 = array('i', [10,20,30,40,50])

for x in array1:
   print(x)

输出

当我们编译并执行上面的程序时,它会产生以下结果 -

10
20
30
40
50

访问数组元素

我们可以使用元素的索引来访问数组的每个元素。下面的代码展示了如何访问数组元素。

例子

from array import *

array1 = array('i', [10,20,30,40,50])

print (array1[0])

print (array1[2])

输出

当我们编译并执行上面的程序时,它会产生以下结果,这表明该元素被插入到索引位置1处。

10
30

插入操作

插入操作是将一个或多个数据元素插入到数组中。根据需要,可以在数组的开头、结尾或任何给定索引处添加新元素。

例子

在这里,我们使用 python 内置的 insert() 方法在数组的中间添加一个数据元素。

from array import *

array1 = array('i', [10,20,30,40,50])

array1.insert(1,60)

for x in array1:
   print(x)

当我们编译并执行上面的程序时,它会产生以下结果,表明元素被插入到索引位置 1 处。

输出

10
60
20
30
40
50

删除操作

删除是指从数组中删除一个现有元素并重新组织数组的所有元素。

例子

在这里,我们使用 python 内置的 remove() 方法删除数组中间的数据元素。

from array import *

array1 = array('i', [10,20,30,40,50])

array1.remove(40)

for x in array1:
   print(x)

输出

当我们编译并执行上面的程序时,它会产生以下结果,表明该元素已从数组中删除。

10
20
30
50

搜索操作

您可以根据数组元素的值或索引来搜索该元素。

例子

在这里,我们使用 python 内置的 index() 方法搜索数据元素。

from array import *

array1 = array('i', [10,20,30,40,50])

print (array1.index(40))

输出

当我们编译并执行上面的程序时,它会产生以下结果,显示元素的索引。如果数组中不存在该值,则程序将返回错误。

3

更新操作

更新操作是指更新数组中给定索引处的现有元素。

例子

在这里,我们只需将新值重新分配给我们想要更新的所需索引。

from array import *

array1 = array('i', [10,20,30,40,50])

array1[2] = 80

for x in array1:
   print(x)

输出

当我们编译并执行上面的程序时,它会产生以下结果,显示索引位置 2 处的新值。

10
20
80
40
50

Python - 列表

列表是 Python 中最通用的数据类型,可以将其写为方括号之间以逗号分隔的值(项)的列表。关于列表的重要一点是列表中的项目不必是同一类型。

创建列表就像在方括号之间放置不同的逗号分隔值一样简单。

例如

list1 = ['physics', 'chemistry', 1997, 2000]
list2 = [1, 2, 3, 4, 5 ]
list3 = ["a", "b", "c", "d"]

与字符串索引类似,列表索引从 0 开始,并且列表可以进行切片、连接等。

访问值

要访问列表中的值,请使用方括号与索引一起进行切片,以获得该索引处可用的值。

例如

#!/usr/bin/python

list1 = ['physics', 'chemistry', 1997, 2000]
list2 = [1, 2, 3, 4, 5, 6, 7 ]
print ("list1[0]: ", list1[0])
print ("list2[1:5]: ", list2[1:5])

执行上述代码时,会产生以下结果 -

list1[0]:  physics
list2[1:5]:  [2, 3, 4, 5]

更新列表

您可以通过在赋值运算符左侧给出切片来更新列表中的单个或多个元素,并且可以使用append() 方法添加到列表中的元素。

例如

#!/usr/bin/python

list = ['physics', 'chemistry', 1997, 2000]
print ("Value available at index 2 : ")
print (list[2])
list[2] = 2001
print ("New value available at index 2 : ")
print (list[2])
  • 注意-append() 方法将在后续部分中讨论。

执行上述代码时,会产生以下结果 -

Value available at index 2 :
1997
New value available at index 2 :
2001

删除列表元素

要删除列表元素,如果您确切知道要删除哪个元素,则可以使用 del 语句;如果您不知道,则可以使用remove() 方法。

例如

#!/usr/bin/python

list1 = ['physics', 'chemistry', 1997, 2000]
print (list1)
del list1[2]
print ("After deleting value at index 2 : ")
print (list1)

执行上述代码时,会产生以下结果 -

['physics', 'chemistry', 1997, 2000]
After deleting value at index 2 :
['physics', 'chemistry', 2000]
  • 注意- remove() 方法将在后续部分中讨论。

基本列表操作

列表对 + 和 * 运算符的响应与字符串非常相似;它们在这里也意味着串联和重复,只不过结果是一个新列表,而不是一个字符串。

事实上,列表响应我们在前一章中对字符串使用的所有常规序列操作。

Python 表达式 结果 描述
长度([1,2,3]) 3 长度
[1,2,3] + [4,5,6] [1,2,3,4,5,6] 级联
['嗨!'] * 4 [‘嗨!’、‘嗨!’、‘嗨!’、‘嗨!’] 重复
[1,2,3] 中的 3 真的 会员资格
对于 [1, 2, 3] 中的 x:打印 x, 1 2 3 迭代

Python - 元组

元组是不可变的 Python 对象的序列。元组是序列,就像列表一样。元组和列表之间的区别在于,与列表不同,元组不能更改,并且元组使用括号,而列表使用方括号。

创建元组就像放置不同的逗号分隔值一样简单。您也可以选择将这些逗号分隔值放在括号之间。

例如

tup1 = ('physics', 'chemistry', 1997, 2000);
tup2 = (1, 2, 3, 4, 5 );
tup3 = "a", "b", "c", "d";

空元组被写成两个不包含任何内容的括号 -

tup1 = ();

要编写包含单个值的元组,即使只有一个值,也必须包含逗号 -

tup1 = (50,);

与字符串索引一样,元组索引从 0 开始,并且可以对它们进行切片、连接等。

访问元组中的值

要访问元组中的值,请使用方括号与索引一起进行切片,以获得该索引处可用的值。

例如

#!/usr/bin/python

tup1 = ('physics', 'chemistry', 1997, 2000);
tup2 = (1, 2, 3, 4, 5, 6, 7 );
print ("tup1[0]: ", tup1[0])
print ("tup2[1:5]: ", tup2[1:5])

执行上述代码时,会产生以下结果 -

tup1[0]:  physics
tup2[1:5]:  [2, 3, 4, 5]

更新元组

元组是不可变的,这意味着您无法更新或更改元组元素的值。您可以使用现有元组的一部分来创建新元组,如下例所示 -

#!/usr/bin/python

tup1 = (12, 34.56);
tup2 = ('abc', 'xyz');

# Following action is not valid for tuples
# tup1[0] = 100;

# So let's create a new tuple as follows
tup3 = tup1 + tup2;
print (tup3);

执行上述代码时,会产生以下结果 -

(12, 34.56, 'abc', 'xyz')

删除元组元素

删除单个元组元素是不可能的。当然,将另一个元组放在一起并丢弃不需要的元素并没有什么问题。

要显式删除整个元组,只需使用del语句。

例如

#!/usr/bin/python

tup = ('physics', 'chemistry', 1997, 2000);
print (tup);
del tup;
print ("After deleting tup : ");
print (tup);
  • 注意- 引发异常,这是因为del tup元组不再存在。

这会产生以下结果 -

('physics', 'chemistry', 1997, 2000)
After deleting tup :
Traceback (most recent call last):
   File "test.py", line 9, in <module>
      print tup;
NameError: name 'tup' is not defined

基本元组操作

元组对 + 和 * 运算符的响应与字符串非常相似;它们在这里也意味着连接和重复,只不过结果是一个新的元组,而不是一个字符串。

事实上,元组响应我们在前一章中对字符串使用的所有常规序列操作。

Python 表达式 结果 描述
长度((1,2,3)) 3 长度
(1,2,3) + (4,5,6) (1、2、3、4、5、6) 级联
(“嗨!”,)* 4 (“嗨!”、“嗨!”、“嗨!”、“嗨!”) 重复
3 英寸(1,2,3) 真的 会员资格
对于 (1, 2, 3) 中的 x:打印 x, 1 2 3 迭代

Python-字典

在 Dictionary 中,每个键与其值之间用冒号 (:) 分隔,项目之间用逗号分隔,整个内容用大括号括起来。没有任何项目的空字典仅用两个大括号编写,如下所示 - {}。

键在字典中是唯一的,而值可能不是。字典的值可以是任何类型,但键必须是不可变的数据类型,例如字符串、数字或元组。

访问字典中的值

要访问字典元素,您可以使用熟悉的方括号和键来获取其值。

例子

一个简单的例子如下 -

#!/usr/bin/python

dict = {'Name': 'Zara', 'Age': 7, 'Class': 'First'}
print ("dict['Name']: ", dict['Name'])
print ("dict['Age']: ", dict['Age'])

输出

执行上述代码时,会产生以下结果 -

dict['Name']:  Zara
dict['Age']:  7

如果我们尝试使用不属于字典的键访问数据项,我们会收到如下错误 -

例子

#!/usr/bin/python

dict = {'Name': 'Zara', 'Age': 7, 'Class': 'First'}
print ("dict['Alice']: ", dict['Alice'])

输出

执行上述代码时,会产生以下结果 -

dict['Alice']:
Traceback (most recent call last):
   File "test.py", line 4, in <module>
      print "dict['Alice']: ", dict['Alice'];
KeyError: 'Alice'

更新词典

您可以通过添加新条目或键值对、修改现有条目或删除现有条目来更新字典,如下面的简单示例所示 -

例子

#!/usr/bin/python

dict = {'Name': 'Zara', 'Age': 7, 'Class': 'First'}
dict['Age'] = 8; # update existing entry
dict['School'] = "DPS School"; # Add new entry

print ("dict['Age']: ", dict['Age'])
print ("dict['School']: ", dict['School'])

输出

执行上述代码时,会产生以下结果 -

dict['Age']:  8
dict['School']:  DPS School

删除字典元素

您可以删除单个字典元素或清除字典的全部内容。您还可以通过一次操作删除整个字典。

例子

要显式删除整个字典,只需使用del语句。一个简单的例子如下 -

#!/usr/bin/python

dict = {'Name': 'Zara', 'Age': 7, 'Class': 'First'}
del dict['Name']; # remove entry with key 'Name'
dict.clear();     # remove all entries in dict
del dict ;        # delete entire dictionary

print ("dict['Age']: ", dict['Age'])
print ("dict['School']: ", dict['School'])
  • 注意- 会引发异常,因为del dict字典不再存在 -

输出

这会产生以下结果 -

dict['Age']:  dict['Age']
dict['School']:  dict['School']
  • 注意- del() 方法将在后续部分中讨论。

字典键的属性

字典值没有限制。它们可以是任意 Python 对象,可以是标准对象,也可以是用户定义的对象。然而,对于按键来说却并非如此。

关于字典键有两点需要记住 -

  • 每个键不允许有多个条目。这意味着不允许有重复的密钥。当分配过程中遇到重复键时,最后一次分配获胜。

例如

#!/usr/bin/python

dict = {'Name': 'Zara', 'Age': 7, 'Name': 'Manni'}
print ("dict['Name']: ", dict['Name'])

输出

执行上述代码时,会产生以下结果 -

dict['Name']:  Manni

键必须是不可变的。这意味着您可以使用字符串、数字或元组作为字典键,但不允许使用 ['key'] 之类的内容。

例子

一个例子如下 -

#!/usr/bin/python

dict = {['Name']: 'Zara', 'Age': 7}
print ("dict['Name']: ", dict['Name'])

输出

执行上述代码时,会产生以下结果 -

Traceback (most recent call last):
   File "test.py", line 3, in <module>
      dict = {['Name']: 'Zara', 'Age': 7};
TypeError: list objects are unhashable

Python - 二维数组

二维数组是数组中的数组。它是一个数组的数组。在这种类型的数组中,数据元素的位置由两个索引而不是一个索引引用。所以它代表一个包含行和数据列的表。

在下面的二维数组示例中,观察每个数组元素本身也是一个数组。

考虑每天记录温度 4 次的示例。有时记录仪器可能出现故障,导致我们无法记录数据。4 天的数据可以表示为二维数组,如下所示。

Day 1 - 11 12 5 2 
Day 2 - 15 6 10 
Day 3 - 10 8 12 5 
Day 4 - 12 15 8 6 

上述数据可以表示为如下二维数组。

T = [[11, 12, 5, 2], [15, 6,10], [10, 8, 12, 5], [12,15,8,6]]

访问值

可以使用两个索引来访问二维数组中的数据元素。一个索引引用主数组或父数组,另一个索引引用内部数组中数据元素的位置。如果我们仅提及一个索引,则将打印该索引位置的整个内部数组。

例子

下面的例子说明了它是如何工作的。

from array import *

T = [[11, 12, 5, 2], [15, 6,10], [10, 8, 12, 5], [12,15,8,6]]

print(T[0])

print(T[1][2])

输出

执行上述代码时,会产生以下结果 -

[11, 12, 5, 2]
10

要打印整个二维数组,我们可以使用 python for 循环,如下所示。我们使用行尾来打印不同行中的值。

例子

from array import *

T = [[11, 12, 5, 2], [15, 6,10], [10, 8, 12, 5], [12,15,8,6]]
for r in T:
   for c in r:
      print(c,end = " ")
   print()

输出

执行上述代码时,会产生以下结果 -

11 12  5 2 
15  6 10 
10  8 12 5 
12 15  8 6 

插入值

我们可以使用 insert() 方法并指定索引在特定位置插入新数据元素。

例子

在下面的示例中,一个新数据元素插入到索引位置 2 处。

from array import *
T = [[11, 12, 5, 2], [15, 6,10], [10, 8, 12, 5], [12,15,8,6]]

T.insert(2, [0,5,11,13,6])

for r in T:
   for c in r:
      print(c,end = " ")
   print()

输出

执行上述代码时,会产生以下结果 -

11 12  5  2 
15  6 10 
 0  5 11 13 6 
10  8 12  5 
12 15  8  6 

更新值

我们可以通过使用数组索引重新分配值来更新整个内部数组或内部数组的某些特定数据元素。

例子

from array import *

T = [[11, 12, 5, 2], [15, 6,10], [10, 8, 12, 5], [12,15,8,6]]

T[2] = [11,9]
T[0][3] = 7
for r in T:
   for c in r:
      print(c,end = " ")
   print()

输出

执行上述代码时,会产生以下结果 -

11 12 5  7 
15  6 10 
11  9 
12 15 8  6 

删除值

我们可以通过使用带索引的 del() 方法重新分配值来删除整个内部数组或内部数组的某些特定数据元素。但如果您需要删除内部数组之一中的特定数据元素,请使用上述更新过程。

例子

from array import *
T = [[11, 12, 5, 2], [15, 6,10], [10, 8, 12, 5], [12,15,8,6]]

del T[3]

for r in T:
   for c in r:
      print(c,end = " ")
   print()

输出

执行上述代码时,会产生以下结果 -

11 12 5 2 
15 6 10 
10 8 12 5 

Python-矩阵

矩阵是二维数组的特例,其中每个数据元素的大小严格相同。所以每个矩阵也是一个二维数组,但反之则不然。

矩阵对于许多数学和科学计算来说是非常重要的数据结构。由于我们已经在上一章中讨论了二维数组数据结构,因此我们在本章中将重点关注特定于矩阵的数据结构操作。

我们还使用 numpy 包进行矩阵数据操作。

矩阵示例

考虑记录 1 周早上、中午、晚上和午夜测量温度的情况。它可以使用数组和 numpy 中可用的重塑方法呈现为 7X5 矩阵。

from numpy import * 
a = array([['Mon',18,20,22,17],['Tue',11,18,21,18],
   ['Wed',15,21,20,19],['Thu',11,20,22,21],
   ['Fri',18,17,23,22],['Sat',12,22,20,18],
   ['Sun',13,15,19,16]])
m = reshape(a,(7,5))
print(m)

输出

上述数据可以表示为二维数组,如下所示 -

[
   ['Mon' '18' '20' '22' '17']
   ['Tue' '11' '18' '21' '18']
   ['Wed' '15' '21' '20' '19']
   ['Thu' '11' '20' '22' '21']
   ['Fri' '18' '17' '23' '22']
   ['Sat' '12' '22' '20' '18']
   ['Sun' '13' '15' '19' '16']
]

访问值

可以使用索引来访问矩阵中的数据元素。访问方式与二维数组中数据的访问方式相同。

例子

from numpy import * 
m = array([['Mon',18,20,22,17],['Tue',11,18,21,18],
   ['Wed',15,21,20,19],['Thu',11,20,22,21],
   ['Fri',18,17,23,22],['Sat',12,22,20,18],
   ['Sun',13,15,19,16]])
    
# Print data for Wednesday
print(m[2])

# Print data for friday evening
print(m[4][3])

输出

执行上述代码时,会产生以下结果 -

['Wed', 15, 21, 20, 19]
23

添加一行

使用下面提到的代码在矩阵中添加一行。

例子

from numpy import * 
m = array([['Mon',18,20,22,17],['Tue',11,18,21,18],
   ['Wed',15,21,20,19],['Thu',11,20,22,21],
   ['Fri',18,17,23,22],['Sat',12,22,20,18],
   ['Sun',13,15,19,16]])
m_r = append(m,[['Avg',12,15,13,11]],0)

print(m_r)

输出

执行上述代码时,会产生以下结果 -

[
   ['Mon' '18' '20' '22' '17']
   ['Tue' '11' '18' '21' '18']
   ['Wed' '15' '21' '20' '19']
   ['Thu' '11' '20' '22' '21']
   ['Fri' '18' '17' '23' '22']
   ['Sat' '12' '22' '20' '18']
   ['Sun' '13' '15' '19' '16']
   ['Avg' '12' '15' '13' '11']
]

添加列

我们可以使用 insert() 方法向矩阵添加列。这里我们必须提到要添加列的索引和一个包含所添加列的新值的数组。在下面的示例中,我们在从开始的第五个位置添加新列。

例子

from numpy import * 
m = array([['Mon',18,20,22,17],['Tue',11,18,21,18],
   ['Wed',15,21,20,19],['Thu',11,20,22,21],
   ['Fri',18,17,23,22],['Sat',12,22,20,18],
   ['Sun',13,15,19,16]])
m_c = insert(m,[5],[[1],[2],[3],[4],[5],[6],[7]],1)

print(m_c)

输出

执行上述代码时,会产生以下结果 -

[
   ['Mon' '18' '20' '22' '17' '1']
   ['Tue' '11' '18' '21' '18' '2']
   ['Wed' '15' '21' '20' '19' '3']
   ['Thu' '11' '20' '22' '21' '4']
   ['Fri' '18' '17' '23' '22' '5']
   ['Sat' '12' '22' '20' '18' '6']
   ['Sun' '13' '15' '19' '16' '7']
]

删除一行

我们可以使用 delete() 方法从矩阵中删除一行。我们必须指定行的索引以及轴值,0 表示行,1 表示列。

例子

from numpy import * 
m = array([['Mon',18,20,22,17],['Tue',11,18,21,18],
   ['Wed',15,21,20,19],['Thu',11,20,22,21],
   ['Fri',18,17,23,22],['Sat',12,22,20,18],
   ['Sun',13,15,19,16]])
m = delete(m,[2],0)

print(m)

输出

执行上述代码时,会产生以下结果 -

[
   ['Mon' '18' '20' '22' '17']
   ['Tue' '11' '18' '21' '18']
   ['Thu' '11' '20' '22' '21']
   ['Fri' '18' '17' '23' '22']
   ['Sat' '12' '22' '20' '18']
   ['Sun' '13' '15' '19' '16']
]

删除一列

我们可以使用 delete() 方法从矩阵中删除一列。我们必须指定列的索引以及轴值,0 表示行,1 表示列。

例子

from numpy import * 
m = array([['Mon',18,20,22,17],['Tue',11,18,21,18],
   ['Wed',15,21,20,19],['Thu',11,20,22,21],
   ['Fri',18,17,23,22],['Sat',12,22,20,18],
   ['Sun',13,15,19,16]])
m = delete(m,s_[2],1)

print(m)

输出

执行上述代码时,会产生以下结果 -

[
   ['Mon' '18' '22' '17']
   ['Tue' '11' '21' '18']
   ['Wed' '15' '20' '19']
   ['Thu' '11' '22' '21']
   ['Fri' '18' '23' '22']
   ['Sat' '12' '20' '18']
   ['Sun' '13' '19' '16']
]

更新一行

要更新矩阵行中的值,我们只需重新分配行索引处的值即可。在下面的示例中,星期四数据的所有值都标记为零。该行的索引为 3。

例子

from numpy import * 
m = array([['Mon',18,20,22,17],['Tue',11,18,21,18],
   ['Wed',15,21,20,19],['Thu',11,20,22,21],
   ['Fri',18,17,23,22],['Sat',12,22,20,18],
   ['Sun',13,15,19,16]])
m[3] = ['Thu',0,0,0,0]

print(m)

输出

执行上述代码时,会产生以下结果 -

[
   ['Mon' '18' '20' '22' '17']
   ['Tue' '11' '18' '21' '18']
   ['Wed' '15' '21' '20' '19']
   ['Thu' '0' '0' '0' '0']
   ['Fri' '18' '17' '23' '22']
   ['Sat' '12' '22' '20' '18']
   ['Sun' '13' '15' '19' '16']
]

Python - 集合

从数学上讲,集合是不按任何特定顺序排列的项目的集合。Python 集与此数学定义类似,但具有以下附加条件。

  • 集合中的元素不能重复。

  • 集合中的元素是不可变的(无法修改),但集合作为一个整体是可变的。

  • python 集合中的任何元素都没有附加索引。因此它们不支持任何索引或切片操作。

设置操作

Python 中的集合通常用于数学运算,如并、交、差和补等。我们可以创建一个集合,访问它的元素并执行这些数学运算,如下所示。

创建一个集合

集合是通过使用 set() 函数或将所有元素放在一对大括号内来创建的。

例子

Days=set(["Mon","Tue","Wed","Thu","Fri","Sat","Sun"])
Months={"Jan","Feb","Mar"}
Dates={21,22,17}
print(Days)
print(Months)
print(Dates)

输出

当执行上面的代码时,会产生以下结果。请注意结果中元素顺序的变化。

set(['Wed', 'Sun', 'Fri', 'Tue', 'Mon', 'Thu', 'Sat'])
set(['Jan', 'Mar', 'Feb'])
set([17, 21, 22])

访问集合中的值

我们无法访问集合中的单个值。我们只能一起访问所有元素,如上所示。但我们也可以通过循环遍历集合来获取单个元素的列表。

例子

Days=set(["Mon","Tue","Wed","Thu","Fri","Sat","Sun"])
 
for d in Days:
   print(d)

输出

执行上述代码时,会产生以下结果 -

Wed
Sun
Fri
Tue
Mon
Thu
Sat

将项目添加到集合中

我们可以使用 add() 方法将元素添加到集合中。再次正如所讨论的,新添加的元素没有附加特定的索引。

例子

Days=set(["Mon","Tue","Wed","Thu","Fri","Sat"])
 
Days.add("Sun")
print(Days)

输出

执行上述代码时,会产生以下结果 -

set(['Wed', 'Sun', 'Fri', 'Tue', 'Mon', 'Thu', 'Sat'])

从集合中删除项目

我们可以使用discard()方法从集合中删除元素。再次正如所讨论的,新添加的元素没有附加特定的索引。

例子

Days=set(["Mon","Tue","Wed","Thu","Fri","Sat"])
 
Days.discard("Sun")
print(Days)

输出

当执行上面的代码时,会产生以下结果。

set(['Wed', 'Fri', 'Tue', 'Mon', 'Thu', 'Sat'])

集合并集

对两个集合进行并集运算会生成一个新集合,其中包含这两个集合中的所有不同元素。在下面的示例中,元素“Wed”同时存在于两个集合中。

例子

DaysA = set(["Mon","Tue","Wed"])
DaysB = set(["Wed","Thu","Fri","Sat","Sun"])
AllDays = DaysA|DaysB
print(AllDays)

输出

当执行上面的代码时,会产生以下结果。请注意,结果只有一个“wed”。

set(['Wed', 'Fri', 'Tue', 'Mon', 'Thu', 'Sat'])

集合的交集

两个集合的交集运算会生成一个新集合,其中仅包含两个集合中的公共元素。在下面的示例中,元素“Wed”同时存在于两个集合中。

例子

DaysA = set(["Mon","Tue","Wed"])
DaysB = set(["Wed","Thu","Fri","Sat","Sun"])
AllDays = DaysA & DaysB
print(AllDays)

输出

当执行上面的代码时,会产生以下结果。请注意,结果只有一个“wed”。

set(['Wed'])

集合的差异

对两个集合进行差分运算会生成一个新集合,其中仅包含第一个集合中的元素,而不包含第二个集合中的元素。在下面的示例中,元素“Wed”同时存在于两个集合中,因此在结果集中找不到它。

例子

DaysA = set(["Mon","Tue","Wed"])
DaysB = set(["Wed","Thu","Fri","Sat","Sun"])
AllDays = DaysA - DaysB
print(AllDays)

输出

当执行上面的代码时,会产生以下结果。请注意,结果只有一个“wed”。

set(['Mon', 'Tue'])

比较集

我们可以检查给定的集合是否是另一个集合的子集或超集。结果是 True 或 False,具体取决于集合中存在的元素。

例子

DaysA = set(["Mon","Tue","Wed"])
DaysB = set(["Mon","Tue","Wed","Thu","Fri","Sat","Sun"])
SubsetRes = DaysA <= DaysB
SupersetRes = DaysB >= DaysA
print(SubsetRes)
print(SupersetRes)

输出

执行上述代码时,会产生以下结果 -

True
True

Python - 地图

Python Maps 也称为 ChainMap,是一种将多个字典作为一个单元进行管理的数据结构。组合字典包含按特定顺序排列的键和值对,消除了任何重复的键。ChainMap 的最佳用途是一次搜索多个字典并获得正确的键值对映射。我们还看到这些 ChainMap 表现为堆栈数据结构。

创建 ChainMap

我们创建两个字典并使用集合库中的 ChainMap 方法将它们组合在一起。然后我们打印字典组合结果的键和值。如果存在重复的键,则仅保留第一个键的值。

例子

import collections

dict1 = {'day1': 'Mon', 'day2': 'Tue'}
dict2 = {'day3': 'Wed', 'day1': 'Thu'}

res = collections.ChainMap(dict1, dict2)

# Creating a single dictionary
print(res.maps,'\n')

print('Keys = {}'.format(list(res.keys())))
print('Values = {}'.format(list(res.values())))
print()

# Print all the elements from the result
print('elements:')
for key, val in res.items():
   print('{} = {}'.format(key, val))
print()

# Find a specific value in the result
print('day3 in res: {}'.format(('day1' in res)))
print('day4 in res: {}'.format(('day4' in res)))

输出

执行上述代码时,会产生以下结果 -

[{'day1': 'Mon', 'day2': 'Tue'}, {'day1': 'Thu', 'day3': 'Wed'}] 

Keys = ['day1', 'day3', 'day2']
Values = ['Mon', 'Wed', 'Tue']

elements:
day1 = Mon
day3 = Wed
day2 = Tue

day3 in res: True
day4 in res: False

地图重新排序

如果我们在上面的示例中将字典组合在一起时更改字典的顺序,我们会看到元素的位置会互换,就好像它们处于连续链中一样。这再次显示了 Maps 作为堆栈的Behave。

例子

import collections

dict1 = {'day1': 'Mon', 'day2': 'Tue'}
dict2 = {'day3': 'Wed', 'day4': 'Thu'}

res1 = collections.ChainMap(dict1, dict2)
print(res1.maps,'\n')

res2 = collections.ChainMap(dict2, dict1)
print(res2.maps,'\n')

输出

执行上述代码时,会产生以下结果 -

[{'day1': 'Mon', 'day2': 'Tue'}, {'day3': 'Wed', 'day4': 'Thu'}] 

[{'day3': 'Wed', 'day4': 'Thu'}, {'day1': 'Mon', 'day2': 'Tue'}] 

更新地图

当字典的元素更新时,结果会立即更新到ChainMap的结果中。在下面的示例中,我们看到新的更新值反映在结果中,而无需再次显式应用 ChainMap 方法。

例子

import collections

dict1 = {'day1': 'Mon', 'day2': 'Tue'}
dict2 = {'day3': 'Wed', 'day4': 'Thu'}

res = collections.ChainMap(dict1, dict2)
print(res.maps,'\n')

dict2['day4'] = 'Fri'
print(res.maps,'\n')

输出

执行上述代码时,会产生以下结果 -

[{'day1': 'Mon', 'day2': 'Tue'}, {'day3': 'Wed', 'day4': 'Thu'}] 

[{'day1': 'Mon', 'day2': 'Tue'}, {'day3': 'Wed', 'day4': 'Fri'}] 

Python - 链表

链表是通过链接连接在一起的数据元素序列。每个数据元素都包含与另一个数据元素的指针形式的连接。Python 的标准库中没有链表。我们使用前一章中讨论的节点概念来实现链表的概念。

我们已经了解了如何创建节点类以及如何遍历节点的元素。在本章中,我们将研究称为单链表的链表类型。在这种类型的数据结构中,任何两个数据元素之间只有一个链接。我们创建这样一个列表,并创建其他方法来插入、更新和删除列表中的元素。

链表的创建

链表是使用我们在上一章中学习的节点类创建的。我们创建一个 Node 对象并创建另一个类来使用这个 ode 对象。我们通过节点对象传递适当的值以指向下一个数据元素。下面的程序创建具有三个数据元素的链表。下一节我们将看到如何遍历链表。

class Node:
   def __init__(self, dataval=None):
      self.dataval = dataval
      self.nextval = None

class SLinkedList:
   def __init__(self):
      self.headval = None

list1 = SLinkedList()
list1.headval = Node("Mon")
e2 = Node("Tue")
e3 = Node("Wed")
# Link first Node to second node
list1.headval.nextval = e2

# Link second Node to third node
e2.nextval = e3

遍历链表

单链表只能从第一个数据元素开始向前遍历。我们只需将下一个节点的指针分配给当前数据元素即可打印下一个数据元素的值。

例子

class Node:
   def __init__(self, dataval=None):
      self.dataval = dataval
      self.nextval = None

class SLinkedList:
   def __init__(self):
      self.headval = None

   def listprint(self):
      printval = self.headval
      while printval is not None:
         print (printval.dataval)
         printval = printval.nextval

list = SLinkedList()
list.headval = Node("Mon")
e2 = Node("Tue")
e3 = Node("Wed")

# Link first Node to second node
list.headval.nextval = e2

# Link second Node to third node
e2.nextval = e3

list.listprint()

输出

执行上述代码时,会产生以下结果 -

Mon
Tue
Wed

插入链表

在链表中插入元素涉及将指针从现有节点重新分配给新插入的节点。根据新数据元素是插入到链表的开头、中间还是末尾,我们有以下情况。

插入到开头

这涉及将新数据节点的下一个指针指向链表的当前头。因此,链表的当前头成为第二个数据元素,新节点成为链表的头。

例子

class Node:
   def __init__(self, dataval=None):
      self.dataval = dataval
      self.nextval = None

class SLinkedList:
   def __init__(self):
      self.headval = None
# Print the linked list
   def listprint(self):
      printval = self.headval
      while printval is not None:
         print (printval.dataval)
         printval = printval.nextval
   def AtBegining(self,newdata):
      NewNode = Node(newdata)

# Update the new nodes next val to existing node
   NewNode.nextval = self.headval
   self.headval = NewNode

list = SLinkedList()
list.headval = Node("Mon")
e2 = Node("Tue")
e3 = Node("Wed")

list.headval.nextval = e2
e2.nextval = e3

list.AtBegining("Sun")
list.listprint()

输出

执行上述代码时,会产生以下结果 -

Sun
Mon
Tue
Wed

插入到最后

这涉及到将链表当前最后一个节点的下一个指针指向新的数据节点。因此链表当前的最后一个节点成为倒数第二个数据节点,新节点成为链表的最后一个节点。

例子

class Node:
   def __init__(self, dataval=None):
      self.dataval = dataval
      self.nextval = None
class SLinkedList:
   def __init__(self):
      self.headval = None
# Function to add newnode
   def AtEnd(self, newdata):
      NewNode = Node(newdata)
      if self.headval is None:
         self.headval = NewNode
         return
      laste = self.headval
      while(laste.nextval):
         laste = laste.nextval
      laste.nextval=NewNode
# Print the linked list
   def listprint(self):
      printval = self.headval
      while printval is not None:
         print (printval.dataval)
         printval = printval.nextval

list = SLinkedList()
list.headval = Node("Mon")
e2 = Node("Tue")
e3 = Node("Wed")

list.headval.nextval = e2
e2.nextval = e3

list.AtEnd("Thu")

list.listprint()

输出

执行上述代码时,会产生以下结果 -

Mon
Tue
Wed
Thu

插入两个数据节点之间

这涉及更改特定节点的指针以指向新节点。这可以通过传入新节点和现有节点(然后将插入新节点)来实现。因此,我们定义了一个附加类,它将新节点的下一个指针更改为中间节点的下一个指针。然后将新节点分配给中间节点的next指针。

class Node:
   def __init__(self, dataval=None):
      self.dataval = dataval
      self.nextval = None
class SLinkedList:
   def __init__(self):
      self.headval = None

# Function to add node
   def Inbetween(self,middle_node,newdata):
      if middle_node is None:
         print("The mentioned node is absent")
         return

      NewNode = Node(newdata)
      NewNode.nextval = middle_node.nextval
      middle_node.nextval = NewNode

# Print the linked list
   def listprint(self):
      printval = self.headval
      while printval is not None:
         print (printval.dataval)
         printval = printval.nextval

list = SLinkedList()
list.headval = Node("Mon")
e2 = Node("Tue")
e3 = Node("Thu")

list.headval.nextval = e2
e2.nextval = e3

list.Inbetween(list.headval.nextval,"Fri")

list.listprint()

输出

执行上述代码时,会产生以下结果 -

Mon
Tue
Fri
Thu

删除项目

我们可以使用该节点的密钥删除现有节点。在下面的程序中,我们找到要删除的节点的前一个节点,然后将该节点的next指针指向要删除的节点的下一个节点。

例子

class Node:
   def __init__(self, data=None):
      self.data = data
      self.next = None
class SLinkedList:
   def __init__(self):
      self.head = None

   def Atbegining(self, data_in):
      NewNode = Node(data_in)
      NewNode.next = self.head
      self.head = NewNode

# Function to remove node
   def RemoveNode(self, Removekey):
      HeadVal = self.head
         
      if (HeadVal is not None):
         if (HeadVal.data == Removekey):
            self.head = HeadVal.next
            HeadVal = None
            return
      while (HeadVal is not None):
         if HeadVal.data == Removekey:
            break
         prev = HeadVal
         HeadVal = HeadVal.next

      if (HeadVal == None):
         return

      prev.next = HeadVal.next
      HeadVal = None

   def LListprint(self):
      printval = self.head
      while (printval):
         print(printval.data),
         printval = printval.next

llist = SLinkedList()
llist.Atbegining("Mon")
llist.Atbegining("Tue")
llist.Atbegining("Wed")
llist.Atbegining("Thu")
llist.RemoveNode("Tue")
llist.LListprint()

输出

执行上述代码时,会产生以下结果 -

Thu
Wed
Mon

Python-堆栈

在英语词典中,“堆栈”一词的意思是将对象排列在另一个对象之上。这与在此数据结构中分配内存的方式相同。它以类似于厨房中一堆盘子叠放在一起的方式存储数据元素。因此,堆栈数据结构允许在一端(称为堆栈顶部)进行操作。我们只能从堆栈的这一端添加元素或删除元素。

在堆栈中,按顺序最后插入的元素将首先出现,因为我们只能从堆栈顶部删除。这种特征被称为后进先出(LIFO)特征。添加和删​​除元素的操作称为PUSHPOP。在下面的程序中,我们将其实现为添加删除函数。我们声明一个空列表并使用append()和pop()方法来添加和删除数据元素。