Python Data Structure 简明教程

Python Data Structure - Quick Guide

Python - DS Introduction

在此,我们将了解与 Python 编程语言相关的数据结构。

Here, we will understand what is data structure with regards to Python programming language.

Data Structure Overview

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

Data structures are fundamental concepts of computer science which helps is writing efficient programs in any language. Python is a high-level, interpreted, interactive and object-oriented scripting language using which we can study the fundamentals of data structure in a simpler way as compared to other programming languages.

在本章中,我们将学习一些常用数据结构的简短概述,以及它们与一些特定 python 数据类型的关联方式。还有一些特定于 python 的数据结构,被列为另一种类别。

In this chapter we are going to study a short overview of some frequently used data structures in general and how they are related to some specific python data types. There are also some data structures specific to python which is listed as another category.

General Data Structures

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

The various data structures in computer science are divided broadly into two categories shown below. We will discuss about each of the below data structures in detail in subsequent chapters.

Liner Data Structures

这些是按顺序存储数据元素的数据结构。

These are the data structures which store the data elements in a sequential manner.

  1. Array − It is a sequential arrangement of data elements paired with the index of the data element.

  2. Linked List − Each data element contains a link to another element along with the data present in it.

  3. Stack − It is a data structure which follows only to specific order of operation. LIFO(last in First Out) or FILO(First in Last Out).

  4. Queue − It is similar to Stack but the order of operation is only FIFO(First In First Out).

  5. Matrix − It is two dimensional data structure in which the data element is referred by a pair of indices.

Non-Liner Data Structures

这些数据结构中没有数据元素的顺序链接。任何一对或一组数据元素都可以彼此链接,并且可以无需严格的顺序即可访问。

These are the data structures in which there is no sequential linking of data elements. Any pair or group of data elements can be linked to each other and can be accessed without a strict sequence.

  1. Binary Tree − It is a data structure where each data element can be connected to maximum two other data elements and it starts with a root node.

  2. Heap − It is a special case of Tree data structure where the data in the parent node is either strictly greater than/ equal to the child nodes or strictly less than it’s child nodes.

  3. Hash Table − It is a data structure which is made of arrays associated with each other using a hash function. It retrieves values using keys rather than index from a data element.

  4. Graph − It is an arrangement of vertices and nodes where some of the nodes are connected to each other through links.

Python Specific Data Structures

这些数据结构特定于 python 语言,它们在 python 环境中存储不同类型的数据和更快处理数据方面提供了更大的灵活性。

These data structures are specific to python language and they give greater flexibility in storing different types of data and faster processing in python environment.

  1. List − It is similar to array with the exception that the data elements can be of different data types. You can have both numeric and string data in a python list.

  2. Tuple − Tuples are similar to lists but they are immutable which means the values in a tuple cannot be modified they can only be read.

  3. Dictionary − The dictionary contains Key-value pairs as its data elements.

在下一章中,我们将学习如何使用 Python 实现这些每个数据结构的详细信息。

In the next chapters we are going to learn the details of how each of these data structures can be implemented using Python.

Python - DS Environment

Python 可用于各种平台,包括 Linux 和 Mac OS X。让我们了解如何设置我们的 Python 环境。

Python is available on a wide variety of platforms including Linux and Mac OS X. Let’s understand how to set up our Python environment.

Local Environment Setup

打开一个终端窗口并输入“python”以找出它是否已经安装,以及安装的是哪个版本。

Open a terminal window and type "python" to find out if it is already installed and which version is installed.

  1. Unix (Solaris, Linux, FreeBSD, AIX, HP/UX, SunOS, IRIX, etc.)

  2. Win 9x/NT/2000

  3. Macintosh (Intel, PPC, 68K)

  4. OS/2

  5. DOS (multiple versions)

  6. PalmOS

  7. Nokia mobile phones

  8. Windows CE

  9. Acorn/RISC OS

  10. BeOS

  11. Amiga

  12. VMS/OpenVMS

  13. QNX

  14. VxWorks

  15. Psion

  16. Python has also been ported to the Java and .NET virtual machines

Getting Python

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

The most up-to-date and current source code, binaries, documentation, news, etc., is available on the official website of Python www.python.org

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

You can download Python documentation from this website given herewith,www.python.org/doc. The documentation is available in HTML, PDF, and PostScript formats.

Installing Python

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

Python distribution is available for a wide variety of platforms. You need to download only the binary code applicable for your platform and install Python.

如果你的平台没有二进制代码,你需要 C 编译器来手动编译源代码。编译源代码在安装中所需特性的选择方面提供了更大的灵活性。

If the binary code for your platform is not available, you need a C compiler to compile the source code manually. Compiling the source code offers more flexibility in terms of choice of features that you require in your installation.

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

Here is a quick overview of installing Python on various platforms −

Unix and Linux Installation

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

Here are the simple steps to install Python on Unix/Linux machine.

  1. Open a Web browser and go to www.python.org/downloads.

  2. Follow the link to download zipped source code available for Unix/Linux.

  3. Download and extract files.

  4. Editing the Modules/Setup file if you want to customize some options.

  5. run ./configure script

  6. make

  7. make install

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

This installs Python at standard location /usr/local/bin and its libraries at /usr/local/lib/pythonXX where XX is the version of Python.

Windows Installation

以下是如何在 Windows 机器上安装 Python:

Here are the steps to install Python on Windows machine.

  1. Open a Web browser and go to www.python.org/downloads.

  2. Follow the link for the Windows installer python-XYZ.msi file where XYZ is the version you need to install.

  3. To use this installer python-XYZ.msi, the Windows system must support Microsoft Installer 2.0. Save the installer file to your local machine and then run it to find out if your machine supports MSI.

  4. Run the downloaded file. This brings up the Python install wizard, which is really easy to use. Just accept the default settings, wait until the install is finished, and you are done.

Macintosh Installation

最新款的 Mac 电脑都内置了 Python,但可能会有好几年的时差。请参见 www.python.org/download/mac/ 以获取有关同时与支持 Mac 开发的额外工具一起获取当前版本的说明。对于在 Mac OS X 10.3(2003 年发布)之前的较旧的 Mac 操作系统,MacPython 可用。

Recent Macs come with Python installed, but it may be several years out of date. See www.python.org/download/mac/ for instructions on getting the current version along with extra tools to support development on the Mac. For older Mac OS’s before Mac OS X 10.3 (released in 2003), MacPython is available.

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

Jack Jansen maintains it and you can have full access to the entire documentation at his website − http://www.cwi.nl/jack/macpython.html. You can find complete installation details for Mac OS installation.

Setting up PATH

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

Programs and other executable files can be in many directories, so operating systems provide a search path that lists the directories that the OS searches for executables.

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

The path is stored in an environment variable, which is a named string maintained by the operating system. This variable contains information available to the command shell and other programs.

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

The path variable is named as PATH in Unix or Path in Windows (Unix is case sensitive; Windows is not).

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

In Mac OS, the installer handles the path details. To invoke the Python interpreter from any particular directory, you must add the Python directory to your path.

Setting path at Unix/Linux

要在 Unix 中为特定会话将 Python 目录添加到路径中 −

To add the Python directory to the path for a particular session in Unix −

  1. In the csh shell − type setenv PATH "$PATH:/usr/local/bin/python" and press Enter.

  2. In the bash shell (Linux) − type export ATH="$PATH:/usr/local/bin/python" and press Enter.

  3. In the sh or ksh shell − type PATH="$PATH:/usr/local/bin/python" and press Enter.

  4. Note − /usr/local/bin/python is the path of the Python directory

Setting path at Windows

要在Windows特定会话的路径中添加Python目录:

To add the Python directory to the path for a particular session in Windows −

  1. At the command prompt − type path %path%;C:\Python and press Enter.

  2. Note − C:\Python is the path of the Python directory

Python Environment Variables

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

Here are important environment variables, which can be recognized by Python −

Sr.No.

Variable & Description

1

PYTHONPATH It has a role similar to PATH. This variable tells the Python interpreter where to locate the module files imported into a program. It should include the Python source library directory and the directories containing Python source code. PYTHONPATH is sometimes preset by the Python installer.

2

PYTHONSTARTUP It contains the path of an initialization file containing Python source code. It is executed every time you start the interpreter. It is named as .pythonrc.py in Unix and it contains commands that load utilities or modify PYTHONPATH.

3

PYTHONCASEOK It is used in Windows to instruct Python to find the first case-insensitive match in an import statement. Set this variable to any value to activate it.

4

PYTHONHOME It is an alternative module search path. It is usually embedded in the PYTHONSTARTUP or PYTHONPATH directories to make switching module libraries easy.

Running Python

有三种不同的方法来启动 Python,如下所示 −

There are three different ways to start Python, which are as follows −

Interactive Interpreter

  1. You can start Python from Unix, DOS, or any other system that provides you a command-line interpreter or shell window.

  2. Enter python the command line.

  3. Start coding right away in the interactive interpreter.

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

以下是所有可用命令行选项的列表,如下所示 −

Here is the list of all the available command line options, which is as mentioned below −

Sr.No.

Option & Description

1

-d It provides debug output.

2

-O It generates optimized bytecode (resulting in .pyo files).

3

-S Do not run import site to look for Python paths on startup.

4

-v verbose output (detailed trace on import statements).

5

-X disable class-based built-in exceptions (just use strings); obsolete starting with version 1.6.

6

-c cmd run Python script sent in as cmd string

7

file run Python script from given file

Script from the Command-line

可通过 invoking the interpreter on your application,在命令行中执行 Python 脚本,如下所示:

A Python script can be executed at command line by invoking the interpreter on your application, as in the following −

$python script.py # Unix/Linux

or

python% script.py # Unix/Linux

or

C: >python script.py # Windows/DOS
  1. Note − Be sure the file permission mode allows execution.

Integrated Development Environment(IDE)

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

You can run Python from a Graphical User Interface (GUI) environment as well, if you have a GUI application on your system that supports Python.

  1. Unix − IDLE is the very first Unix IDE for Python.

  2. Windows − PythonWin is the first Windows interface for Python and is an IDE with a GUI.

  3. Macintosh − The Macintosh version of Python along with the IDLE IDE is available from the main website, downloadable as either MacBinary or BinHex’d files.

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

If you are not able to set up the environment properly, then you can take help from your system admin. Make sure the Python environment is properly set up and working perfectly fine.

  1. Note − All the examples given in subsequent chapters are executed with Python 2.4.3 version available on CentOS flavor of Linux.

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

We already have set up Python Programming environment online, so that you can execute all the available examples online at the same time when you are learning theory. Feel free to modify any example and execute it online.

Python - Arrays

数组是一个容器,它可以保存一个固定数量的项,并且这些项应该属于同一种类型。大多数数据结构利用数组来实现其算法。以下是了解数组概念的重要术语:

Array is a container which can hold a fix number of items and these items should be of the same type. Most of the data structures make use of arrays to implement their algorithms. Following are the important terms to understand the concept of Array are as follows −

  1. Element − Each item stored in an array is called an element.

  2. Index − Each location of an element in an array has a numerical index, which is used to identify the element.

Array Representation

数组可以在不同的语言中以不同的方式声明。下面是一个说明。

Arrays can be declared in various ways in different languages. Below is an illustration.

array declaration
array representation

根据上述插图,以下是要考虑的重要要点:

As per the above illustration, following are the important points to be considered −

  1. Index starts with 0.

  2. Array length is 10, which means it can store 10 elements.

  3. Each element can be accessed via its index. For example, we can fetch an element at index 6 as 9.

Basic Operations

数组支持的基本操作如下所述:

The basic operations supported by an array are as stated below −

  1. Traverse − print all the array elements one by one.

  2. Insertion − Adds an element at the given index.

  3. Deletion − Deletes an element at the given index.

  4. Search − Searches an element using the given index or by the value.

  5. Update − Updates an element at the given index.

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

Array is created in Python by importing array module to the python program. Then, the array is declared as shown below −

from array import *

arrayName = array(typecode, [Initializers])

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

Typecode are the codes that are used to define the type of value the array will hold. Some common typecodes used are as follows −

Typecode

Value

b

Represents signed integer of size 1 byte

B

Represents unsigned integer of size 1 byte

c

Represents character of size 1 byte

i

Represents signed integer of size 2 bytes

I

Represents unsigned integer of size 2 bytes

f

Represents floating point of size 4 bytes

d

Represents floating point of size 8 bytes

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

Before looking at various array operations lets create and print an array using python.

Example

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

The below code creates an array named array1.

from array import *

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

for x in array1:
   print(x)

Output

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

When we compile and execute the above program, it produces the following result −

10
20
30
40
50

Accessing Array Element

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

We can access each element of an array using the index of the element. The below code shows how to access an array element.

Example

from array import *

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

print (array1[0])

print (array1[2])

Output

当我们编译并执行上述程序时,它会产生以下结果,该结果显示元素插入在索引位置1。

When we compile and execute the above program, it produces the following result, which shows the element is inserted at index position 1.

10
30

Insertion Operation

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

Insert operation is to insert one or more data elements into an array. Based on the requirement, a new element can be added at the beginning, end, or any given index of array.

Example

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

Here, we add a data element at the middle of the array using the python in-built insert() method.

from array import *

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

array1.insert(1,60)

for x in array1:
   print(x)

当我们编译并执行上述程序时,它会产生以下结果,显示元素插入到索引位置 1。

When we compile and execute the above program, it produces the following result which shows the element is inserted at index position 1.

Output

10
60
20
30
40
50

Deletion Operation

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

Deletion refers to removing an existing element from the array and re-organizing all elements of an array.

Example

在此,我们使用 Python 内置 remove() 方法,从数组中间移除一个数据元素。

Here, we remove a data element at the middle of the array using the python in-built remove() method.

from array import *

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

array1.remove(40)

for x in array1:
   print(x)

Output

当我们编译并执行上述程序时,它会产生以下结果,显示该元素已从数组中移除。

When we compile and execute the above program, it produces the following result which shows the element is removed form the array.

10
20
30
50

Search Operation

您可以根据数组元素的值或其索引对其进行搜索。

You can perform a search for an array element based on its value or its index.

Example

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

Here, we search a data element using the python in-built index() method.

from array import *

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

print (array1.index(40))

Output

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

When we compile and execute the above program, it produces the following result which shows the index of the element. If the value is not present in the array then th eprogram returns an error.

3

Update Operation

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

Update operation refers to updating an existing element from the array at a given index.

Example

在这里,我们只需为我们想要更新的目标索引重新指定一个新值。

Here, we simply reassign a new value to the desired index we want to update.

from array import *

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

array1[2] = 80

for x in array1:
   print(x)

Output

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

When we compile and execute the above program, it produces the following result which shows the new value at the index position 2.

10
20
80
40
50

Python - Lists

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

The list is a most versatile datatype available in Python which can be written as a list of comma-separated values (items) between square brackets. Important thing about a list is that items in a list need not be of the same type.

只需在方括号中放置不同的逗号分隔值即可创建列表。

Creating a list is as simple as putting different comma-separated values between square brackets.

For example

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

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

Similar to string indices, list indices start at 0, and lists can be sliced, concatenated and so on.

Accessing Values

要访问列表中的值,请使用方括号以及索引或索引来获取在该索引处可用的值。

To access values in lists, use the square brackets for slicing along with the index or indices to obtain value available at that index.

For example

#!/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])

执行上述代码后,将生成以下结果 −

When the above code is executed, it produces the following result −

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

Updating Lists

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

You can update single or multiple elements of lists by giving the slice on the left-hand side of the assignment operator, and you can add to elements in a list with the append() method.

For example

#!/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])
  1. Note − append() method is discussed in subsequent section.

执行上述代码后,将生成以下结果 −

When the above code is executed, it produces the following result −

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

Delete List Elements

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

To remove a list element, you can use either the del statement if you know exactly which element(s) you are deleting or the remove() method if you do not know.

For example

#!/usr/bin/python

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

当执行以上代码时,它生成以下结果 −

When the above code is executed, it produces following result −

['physics', 'chemistry', 1997, 2000]
After deleting value at index 2 :
['physics', 'chemistry', 2000]
  1. Note − remove() method is discussed in subsequent section.

Basic List Operations

列表对 + 和 * 运算符的响应非常类似于字符串;在此,它们也表示连接和重复,但结果是一个新列表,而不是一个字符串。

Lists respond to the + and * operators much like strings; they mean concatenation and repetition here too, except that the result is a new list, not a string.

实际上,列表对我们在上一章中对字符串使用过的所有常规序列运算都做出响应。

In fact, lists respond to all of the general sequence operations we used on strings in the prior chapter.

Python Expression

Results

Description

len([1, 2, 3])

3

Length

[1, 2, 3] + [4, 5, 6]

[1, 2, 3, 4, 5, 6]

Concatenation

['Hi!'] * 4

['Hi!', 'Hi!', 'Hi!', 'Hi!']

Repetition

3 in [1, 2, 3]

True

Membership

for x in [1, 2, 3]: print x,

1 2 3

Iteration

Python - Tuples

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

A tuple is a sequence of immutable Python objects. Tuples are sequences, just like lists. The differences between tuples and lists are, the tuples cannot be changed unlike lists and tuples use parentheses, whereas lists use square brackets.

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

Creating a tuple is as simple as putting different comma-separated values. Optionally you can put these comma-separated values between parentheses also.

For example

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

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

The empty tuple is written as two parentheses containing nothing −

tup1 = ();

即使只有一个值,为了写一个包含一个值的元组,你也必须包含一个逗号——

To write a tuple containing a single value you have to include a comma, even though there is only one value −

tup1 = (50,);

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

Like string indices, tuple indices start at 0, and they can be sliced, concatenated, and so on.

Accessing Values in Tuples

要访问元组中的值,请使用方括号进行切片,同时使用索引获取该索引处可用的值。

To access values in tuple, use the square brackets for slicing along with the index or indices to obtain value available at that index.

For example

#!/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])

执行上述代码后,将生成以下结果 −

When the above code is executed, it produces the following result −

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

Updating Tuples

元组是不可变的,这意味着你不能更新或更改元组元素的值。你可以采用现有元组的一部分来创建新的元组,如下例所示——

Tuples are immutable which means you cannot update or change the values of tuple elements. You are able to take portions of existing tuples to create new tuples as the following example demonstrates −

#!/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);

执行上述代码后,将生成以下结果 −

When the above code is executed, it produces the following result −

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

Delete Tuple Elements

移除单个元组元素是不可能的。当然,将不想要的元素放在一起,然后组合成元组是没有问题的。

Removing individual tuple elements is not possible. There is, of course, nothing wrong with putting together another tuple with the undesired elements discarded.

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

To explicitly remove an entire tuple, just use the del statement.

For example

#!/usr/bin/python

tup = ('physics', 'chemistry', 1997, 2000);
print (tup);
del tup;
print ("After deleting tup : ");
print (tup);
  1. Note − an exception raised, this is because after del tup tuple does not exist anymore.

这会产生以下结果:

This produces the following result −

('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

Basic Tuples Operations

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

Tuples respond to the + and * operators much like strings; they mean concatenation and repetition here too, except that the result is a new tuple, not a string.

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

In fact, tuples respond to all of the general sequence operations we used on strings in the prior chapter.

Python Expression

Results

Description

len1, 2, 3

3

Length

(1, 2, 3) + (4, 5, 6)

(1, 2, 3, 4, 5, 6)

Concatenation

('Hi!',) * 4

('Hi!', 'Hi!', 'Hi!', 'Hi!')

Repetition

3 in (1, 2, 3)

True

Membership

for x in (1, 2, 3): print x,

1 2 3

Iteration

Python - Dictionary

在字典中,每个键都用冒号 (:) 与其值分隔,项目用逗号分隔,整体用花括号括起来。没有项目的空字典只用一对花括号编写,如下所示 − {}。

In Dictionary each key is separated from its value by a colon (:), the items are separated by commas, and the whole thing is enclosed in curly braces. An empty dictionary without any items is written with just two curly braces, like this − {}.

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

Keys are unique within a dictionary while values may not be. The values of a dictionary can be of any type, but the keys must be of an immutable data type such as strings, numbers, or tuples.

Accessing Values in Dictionary

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

To access dictionary elements, you can use the familiar square brackets along with the key to obtain its value.

Example

一个简单的例子如下 −

A simple example is as follows −

#!/usr/bin/python

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

Output

执行上述代码后,将生成以下结果 −

When the above code is executed, it produces the following result −

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

如果我们尝试使用一个键访问一个数据项,该键不是字典的一部分,我们便会得到如下错误 −

If we attempt to access a data item with a key, which is not part of the dictionary, we get an error as follows −

Example

#!/usr/bin/python

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

Output

执行上述代码后,将生成以下结果 −

When the above code is executed, it produces the following result −

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

Updating Dictionary

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

You can update a dictionary by adding a new entry or a key-value pair, modifying an existing entry, or deleting an existing entry as shown below in the simple example −

Example

#!/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'])

Output

执行上述代码后,将生成以下结果 −

When the above code is executed, it produces the following result −

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

Delete Dictionary Elements

你可以移除单个字典元素或清除整个字典的内容。你也可以在单个操作中删除整个字典。

You can either remove individual dictionary elements or clear the entire contents of a dictionary. You can also delete entire dictionary in a single operation.

Example

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

To explicitly remove an entire dictionary, just use the del statement. A simple example is as mentioned below −

#!/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'])
  1. Note −that an exception is raised because after del dict dictionary does not exist any more −

Output

这会产生以下结果:

This produces the following result −

dict['Age']:  dict['Age']
dict['School']:  dict['School']
  1. Note − del() method is discussed in subsequent section.

Properties of Dictionary Keys

词典值没有限制。它们可以是任何任意的 Python 对象,无论是标准对象还是用户定义的对象。但是,键并非如此。

Dictionary values have no restrictions. They can be any arbitrary Python object, either standard objects or user-defined objects. However, same is not true for the keys.

关于字典键,有两个重要的点需要记住 −

There are two important points to remember about dictionary keys −

  1. More than one entry per key not allowed. Which means no duplicate key is allowed. When duplicate keys encountered during assignment, the last assignment wins.

For example

#!/usr/bin/python

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

Output

执行上述代码后,将生成以下结果 −

When the above code is executed, it produces the following result −

dict['Name']:  Manni

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

Keys must be immutable. Which means you can use strings, numbers or tuples as dictionary keys but something like ['key'] is not allowed.

Example

一个例子如下 −

An example is as follows −

#!/usr/bin/python

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

Output

执行上述代码后,将生成以下结果 −

When the above code is executed, it produces the following result −

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

Python - 2-D Array

二维数组是数组中的数组。它是一个数组的数组。在此类型的数组中,数据元素的位置用两个索引引用,而不是一个索引。所以它表示一个带有数据行和列的表格。

Two dimensional array is an array within an array. It is an array of arrays. In this type of array the position of an data element is referred by two indices instead of one. So it represents a table with rows an dcolumns of data.

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

In the below example of a two dimensional array, observer that each array element itself is also an array.

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

Consider the example of recording temperatures 4 times a day, every day. Some times the recording instrument may be faulty and we fail to record data. Such data for 4 days can be presented as a two dimensional array as below.

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

上面的数据可以表示为二维数组,如下所示。

The above data can be represented as a two dimensional array as below.

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

Accessing Values

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

The data elements in two dimesnional arrays can be accessed using two indices. One index referring to the main or parent array and another index referring to the position of the data element in the inner array.If we mention only one index then the entire inner array is printed for that index position.

Example

下面的示例说明了它的工作原理。

The example below illustrates how it works.

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])

Output

执行上述代码后,将生成以下结果 −

When the above code is executed, it produces the following result −

[11, 12, 5, 2]
10

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

To print out the entire two dimensional array we can use python for loop as shown below. We use end of line to print out the values in different rows.

Example

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()

Output

执行上述代码后,将生成以下结果 −

When the above code is executed, it produces the following result −

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

Inserting Values

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

We can insert new data elements at specific position by using the insert() method and specifying the index.

Example

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

In the below example a new data element is inserted at index position 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()

Output

执行上述代码后,将生成以下结果 −

When the above code is executed, it produces the following result −

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

Updating Values

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

We can update the entire inner array or some specific data elements of the inner array by reassigning the values using the array index.

Example

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()

Output

执行上述代码后,将生成以下结果 −

When the above code is executed, it produces the following result −

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

Deleting the Values

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

We can delete the entire inner array or some specific data elements of the inner array by reassigning the values using the del() method with index. But in case you need to remove specific data elements in one of the inner arrays, then use the update process described above.

Example

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()

Output

执行上述代码后,将生成以下结果 −

When the above code is executed, it produces the following result −

11 12 5 2
15 6 10
10 8 12 5

Python - Matrix

矩阵是二维数组的一种特殊情况,其中每个数据元素的大小完全相同。因此,每个矩阵均是二维数组,但反之不然。

Matrix is a special case of two dimensional array where each data element is of strictly same size. So every matrix is also a two dimensional array but not vice versa.

矩阵是对许多数学和科学计算非常重要的数据结构。正如我们在上一章已经讨论过二维数组数据结构一样,本章将重点介绍针对矩阵的数据结构操作。

Matrices are very important data structures for many mathematical and scientific calculations. As we have already discussed two dimnsional array data structure in the previous chapter we will be focusing on data structure operations specific to matrices in this chapter.

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

We also be using the numpy package for matrix data manipulation.

Matrix Example

考虑记录一周内在上午、中午、晚上和午夜测得的温度的情况。可以使用数组和 numpy 中提供的 reshape 方法,以 7X5 矩阵来表示。

Consider the case of recording temprature for 1 week measured in the morning, mid-day, evening and mid-night. It can be presented as a 7X5 matrix using an array and the reshape method available in numpy.

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)

Output

可以用二维数组表示上述数据,如下所示:

The above data can be represented as a two dimensional array as below −

[
   ['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']
]

Accessing Values

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

The data elements in a matrix can be accessed by using the indexes. The access method is same as the way data is accessed in Two dimensional array.

Example

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])

Output

执行上述代码后,将生成以下结果 −

When the above code is executed, it produces the following result −

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

Adding a row

使用以下提到的代码为矩阵添加一行。

Use the below mentioned code to add a row in a matrix.

Example

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)

Output

执行上述代码后,将生成以下结果 −

When the above code is executed, it produces the following result −

[
   ['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']
]

Adding a column

我们可以使用 insert() 方法为矩阵添加一列。在此,我们必须指定要添加列的位置,以及一个包含所添加列的新值的数组。在以下示例中,我们在起始位置添加了一列。

We can add column to a matrix using the insert() method. here we have to mention the index where we want to add the column and a array containing the new values of the columns added.In the below example we add t a new column at the fifth position from the beginning.

Example

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)

Output

执行上述代码后,将生成以下结果 −

When the above code is executed, it produces the following result −

[
   ['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 a row

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

We can delete a row from a matrix using the delete() method. We have to specify the index of the row and also the axis value which is 0 for a row and 1 for a column.

Example

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)

Output

执行上述代码后,将生成以下结果 −

When the above code is executed, it produces the following result −

[
   ['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 a column

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

We can delete a column from a matrix using the delete() method. We have to specify the index of the column and also the axis value which is 0 for a row and 1 for a column.

Example

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)

Output

执行上述代码后,将生成以下结果 −

When the above code is executed, it produces the following result −

[
   ['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']
]

Update a row

为了更新矩阵中行的值,我们只需重新指定行索引处的值。以下示例中,所有星期四的数据值都标记为零。该行的索引为 3。

To update the values in the row of a matrix we simply re-assign the values at the index of the row. In the below example all the values for thrusday’s data is marked as zero. The index for this row is 3.

Example

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)

Output

执行上述代码后,将生成以下结果 −

When the above code is executed, it produces the following result −

[
   ['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 - Sets

在数学上,集合是按任何特定顺序排列的项的集合。Python 集合类似于该数学定义,附加以下条件。

Mathematically a set is a collection of items not in any particular order. A Python set is similar to this mathematical definition with below additional conditions.

  1. The elements in the set cannot be duplicates.

  2. The elements in the set are immutable(cannot be modified) but the set as a whole is mutable.

  3. There is no index attached to any element in a python set. So they do not support any indexing or slicing operation.

Set Operations

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

The sets in python are typically used for mathematical operations like union, intersection, difference and complement etc. We can create a set, access it’s elements and carry out these mathematical operations as shown below.

Creating a set

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

A set is created by using the set() function or placing all the elements within a pair of curly braces.

Example

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

Output

执行以上代码时,它将产生以下结果。请注意结果中元素的顺序如何改变。

When the above code is executed, it produces the following result. Please note how the order of the elements has changed in the result.

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

Accessing Values in a Set

我们无法在集合中访问单个值。我们只能像上面所示那样一起访问所有元素。但是我们也可以通过遍历集合来获取单个元素的列表。

We cannot access individual values in a set. We can only access all the elements together as shown above. But we can also get a list of individual elements by looping through the set.

Example

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

for d in Days:
   print(d)

Output

执行上述代码后,将生成以下结果 −

When the above code is executed, it produces the following result −

Wed
Sun
Fri
Tue
Mon
Thu
Sat

Adding Items to a Set

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

We can add elements to a set by using add() method. Again as discussed there is no specific index attached to the newly added element.

Example

Days=set(["Mon","Tue","Wed","Thu","Fri","Sat"])

Days.add("Sun")
print(Days)

Output

执行上述代码后,将生成以下结果 −

When the above code is executed, it produces the following result −

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

Removing Item from a Set

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

We can remove elements from a set by using discard() method. Again as discussed there is no specific index attached to the newly added element.

Example

Days=set(["Mon","Tue","Wed","Thu","Fri","Sat"])

Days.discard("Sun")
print(Days)

Output

执行以上代码时,它将产生以下结果。

When the above code is executed, it produces the following result.

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

Union of Sets

对两个集合的并集运算产生一个新集合,其中包含两个集合的所有不同元素。在下面的示例中,元素“星期三”存在于两个集合中。

The union operation on two sets produces a new set containing all the distinct elements from both the sets. In the below example the element “Wed” is present in both the sets.

Example

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

Output

执行以上代码时,它将产生以下结果。请注意结果只有一个“星期三”。

When the above code is executed, it produces the following result. Please note the result has only one “wed”.

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

Intersection of Sets

对两个集合的交集运算产生一个新集合,其中仅包含两个集合的公共元素。在下面的示例中,元素“星期三”存在于两个集合中。

The intersection operation on two sets produces a new set containing only the common elements from both the sets. In the below example the element “Wed” is present in both the sets.

Example

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

Output

执行以上代码时,它将产生以下结果。请注意结果只有一个“星期三”。

When the above code is executed, it produces the following result. Please note the result has only one “wed”.

set(['Wed'])

Difference of Sets

对两个集合的差集运算产生一个新集合,其中仅包含第一个集合的元素,而不包含第二个集合中的任何元素。在下面的示例中,元素“星期三”存在于两个集合中,因此不会出现在结果集中。

The difference operation on two sets produces a new set containing only the elements from the first set and none from the second set. In the below example the element “Wed” is present in both the sets so it will not be found in the result set.

Example

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

Output

执行以上代码时,它将产生以下结果。请注意结果只有一个“星期三”。

When the above code is executed, it produces the following result. Please note the result has only one “wed”.

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

Compare Sets

我们可以检查给定的集合是否是另一个集合的子集或超集。结果根据集合中存在的元素确定为 True 或 False。

We can check if a given set is a subset or superset of another set. The result is True or False depending on the elements present in the sets.

Example

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

Output

执行上述代码后,将生成以下结果 −

When the above code is executed, it produces the following result −

True
True

Python - Maps

Python Maps 又称为 ChainMap,是一种数据结构,可同时管理多个字典为一个单位。组合的字典包含特定序列中的键和值对,消除了任何重复的键。ChainMap 的最佳用途是同时搜索多个字典并获得适当的键值对映射。我们还看到这些 ChainMaps 的行为类似堆栈数据结构。

Python Maps also called ChainMap is a type of data structure to manage multiple dictionaries together as one unit. The combined dictionary contains the key and value pairs in a specific sequence eliminating any duplicate keys. The best use of ChainMap is to search through multiple dictionaries at a time and get the proper key-value pair mapping. We also see that these ChainMaps behave as stack data structure.

Creating a ChainMap

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

We create two dictionaries and club them using the ChainMap method from the collections library. Then we print the keys and values of the result of the combination of the dictionaries. If there are duplicate keys, then only the value from the first key is preserved.

Example

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)))

Output

执行上述代码后,将生成以下结果 −

When the above code is executed, it produces the following result −

[{'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

Map Reordering

如果在上例中组合字典时更改字典的顺序,我们会看到元素的位置会像在连续链中一样交换。这再次显示了映射作为堆栈的行为。

If we change the order the dictionaries while clubbing them in the above example we see that the position of the elements get interchanged as if they are in a continuous chain. This again shows the behavior of Maps as stacks.

Example

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')

Output

执行上述代码后,将生成以下结果 −

When the above code is executed, it produces the following result −

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

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

Updating Map

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

When the element of the dictionary is updated, the result is instantly updated in the result of the ChainMap. In the below example we see that the new updated value reflects in the result without explicitly applying the ChainMap method again.

Example

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')

Output

执行上述代码后,将生成以下结果 −

When the above code is executed, it produces the following result −

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

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

Python - Linked Lists

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

A linked list is a sequence of data elements, which are connected together via links. Each data element contains a connection to another data element in form of a pointer. Python does not have linked lists in its standard library. We implement the concept of linked lists using the concept of nodes as discussed in the previous chapter.

我们已经看到如何创建节点类以及如何遍历节点的元素。本章中,我们将学习称为单链表的链表类型。在这类数据结构中,在两个数据元素之间只有一个链接。我们创建了这样一个链表并创建了额外的插入、更新和移除链表中元素的方法。

We have already seen how we create a node class and how to traverse the elements of a node.In this chapter we are going to study the types of linked lists known as singly linked lists. In this type of data structure there is only one link between any two data elements. We create such a list and create additional methods to insert, update and remove elements from the list.

Creation of Linked list

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

A linked list is created by using the node class we studied in the last chapter. We create a Node object and create another class to use this ode object. We pass the appropriate values through the node object to point the to the next data elements. The below program creates the linked list with three data elements. In the next section we will see how to traverse the linked list.

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

Traversing a Linked List

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

Singly linked lists can be traversed in only forward direction starting form the first data element. We simply print the value of the next data element by assigning the pointer of the next node to the current data element.

Example

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()

Output

执行上述代码后,将生成以下结果 −

When the above code is executed, it produces the following result −

Mon
Tue
Wed

Insertion in a Linked List

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

Inserting element in the linked list involves reassigning the pointers from the existing nodes to the newly inserted node. Depending on whether the new data element is getting inserted at the beginning or at the middle or at the end of the linked list, we have the below scenarios.

Inserting at the Beginning

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

This involves pointing the next pointer of the new data node to the current head of the linked list. So the current head of the linked list becomes the second data element and the new node becomes the head of the linked list.

Example

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()

Output

执行上述代码后,将生成以下结果 −

When the above code is executed, it produces the following result −

Sun
Mon
Tue
Wed

Inserting at the End

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

This involves pointing the next pointer of the the current last node of the linked list to the new data node. So the current last node of the linked list becomes the second last data node and the new node becomes the last node of the linked list.

Example

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()

Output

执行上述代码后,将生成以下结果 −

When the above code is executed, it produces the following result −

Mon
Tue
Wed
Thu

Inserting in between two Data Nodes

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

This involves changing the pointer of a specific node to point to the new node. That is possible by passing in both the new node and the existing node after which the new node will be inserted. So we define an additional class which will change the next pointer of the new node to the next pointer of middle node. Then assign the new node to next pointer of the middle node.

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()

Output

执行上述代码后,将生成以下结果 −

When the above code is executed, it produces the following result −

Mon
Tue
Fri
Thu

Removing an Item

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

We can remove an existing node using the key for that node. In the below program we locate the previous node of the node which is to be deleted.Then, point the next pointer of this node to the next node of the node to be deleted.

Example

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()

Output

执行上述代码后,将生成以下结果 −

When the above code is executed, it produces the following result −

Thu
Wed
Mon

Python - Stack

在英文词典中,堆栈一词意味着在一个物体上排列另一个物体。就像在这种数据结构中分配内存。它以类似的方式存储数据元素,就像一叠盘子在厨房中一个放在另一个上面。因此,堆栈数据结构允许在可以称为堆栈顶部的某一端进行操作。我们只能从堆栈的这个结尾添加元素或删除元素。

In the english dictionary the word stack means arranging objects on over another. It is the same way memory is allocated in this data structure. It stores the data elements in a similar fashion as a bunch of plates are stored one above another in the kitchen. So stack data strcuture allows operations at one end wich can be called top of the stack.We can add elements or remove elements only form this en dof the stack.

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

In a stack the element insreted last in sequence will come out first as we can remove only from the top of the stack. Such feature is known as Last in First Out(LIFO) feature. The operations of adding and removing the elements is known as PUSH and POP. In the following program we implement it as add and and remove functions. We declare an empty list and use the append() and pop() methods to add and remove the data elements.

PUSH into a Stack

让我们了解如何在堆栈中使用 PUSH。参考下面提到的程序−

Let us understand, how to use PUSH in Stack. Refer the program mentioned program below −

Example

class Stack:
   def __init__(self):
      self.stack = []

   def add(self, dataval):
# Use list append method to add element
      if dataval not in self.stack:
         self.stack.append(dataval)
         return True
      else:
         return False
# Use peek to look at the top of the stack
   def peek(self):
	   return self.stack[-1]

AStack = Stack()
AStack.add("Mon")
AStack.add("Tue")
AStack.peek()
print(AStack.peek())
AStack.add("Wed")
AStack.add("Thu")
print(AStack.peek())

Output

执行上述代码后,将生成以下结果 −

When the above code is executed, it produces the following result −

Tue
Thu

POP from a Stack

众所周知,我们只能从堆栈中删除最顶层的数据元素,我们实现一个这样做的 Python 程序。以下程序中的 remove 函数返回最顶层元素。我们通过首先计算堆栈的大小,然后使用内置的 pop() 方法找到最顶层元素来检查顶层元素。

As we know we can remove only the top most data element from the stack, we implement a python program which does that. The remove function in the following program returns the top most element. we check the top element by calculating the size of the stack first and then use the in-built pop() method to find out the top most element.

class Stack:
   def __init__(self):
      self.stack = []

   def add(self, dataval):
# Use list append method to add element
      if dataval not in self.stack:
         self.stack.append(dataval)
         return True
      else:
         return False

# Use list pop method to remove element
   def remove(self):
      if len(self.stack) <= 0:
         return ("No element in the Stack")
      else:
         return self.stack.pop()

AStack = Stack()
AStack.add("Mon")
AStack.add("Tue")
AStack.add("Wed")
AStack.add("Thu")
print(AStack.remove())
print(AStack.remove())

Output

执行上述代码后,将生成以下结果 −

When the above code is executed, it produces the following result −

Thu
Wed

Python - Queue

我们在日常生活中熟悉队列,因为它是一种等待服务的排队方式。队列数据结构也意味着同样的情况,其中数据元素按队列排列。队列的独特性在于添加和删除项目的方式。项目在一边允许,但在另一边删除。所以它是一种先进先出方法。

We are familiar with queue in our day to day life as we wait for a service. The queue data structure aslo means the same where the data elements are arranged in a queue. The uniqueness of queue lies in the way items are added and removed. The items are allowed at on end but removed form the other end. So it is a First-in-First out method.

可以使用 python 列表实现队列,其中我们可以使用 insert() 和 pop() 方法来添加和删除元素。没有插入,因为数据元素总是添加到队列的末尾。

A queue can be implemented using python list where we can use the insert() and pop() methods to add and remove elements. Their is no insertion as data elements are always added at the end of the queue.

Adding Elements

在下面的示例中,我们创建一个队列类,在其中实施了先进先出方法。我们使用内置的 insert 方法添加数据元素。

In the below example we create a queue class where we implement the First-in-First-Out method. We use the in-built insert method for adding data elements.

Example

class Queue:
   def __init__(self):
      self.queue = list()

   def addtoq(self,dataval):
# Insert method to add element
   if dataval not in self.queue:
      self.queue.insert(0,dataval)
      return True
   return False

   def size(self):
      return len(self.queue)

TheQueue = Queue()
TheQueue.addtoq("Mon")
TheQueue.addtoq("Tue")
TheQueue.addtoq("Wed")
print(TheQueue.size())

Output

执行上述代码后,将生成以下结果 −

When the above code is executed, it produces the following result −

3

Removing Element

在下例中,我们创建一个队列类,其中我们插入数据,然后使用内置的弹出方法删除数据。

In the below example we create a queue class where we insert the data and then remove the data using the in-built pop method.

Example

class Queue:
   def __init__(self):
      self.queue = list()

   def addtoq(self,dataval):
# Insert method to add element
   if dataval not in self.queue:
      self.queue.insert(0,dataval)
      return True
   return False
# Pop method to remove element
   def removefromq(self):
      if len(self.queue)>0:
         return self.queue.pop()
      return ("No elements in Queue!")

TheQueue = Queue()
TheQueue.addtoq("Mon")
TheQueue.addtoq("Tue")
TheQueue.addtoq("Wed")
print(TheQueue.removefromq())
print(TheQueue.removefromq())

Output

执行上述代码后,将生成以下结果 −

When the above code is executed, it produces the following result −

Mon
Tue

Python - Dequeue

双端队列或双向队列支持从任一端添加和移除元素。更为常用的堆栈和队列是双向队列的简化形式,其中输入和输出被限制在单个末端。

A double-ended queue, or deque, supports adding and removing elements from either end. The more commonly used stacks and queues are degenerate forms of deques, where the inputs and outputs are restricted to a single end.

Example

import collections

DoubleEnded = collections.deque(["Mon","Tue","Wed"])
DoubleEnded.append("Thu")

print ("Appended at right - ")
print (DoubleEnded)

DoubleEnded.appendleft("Sun")
print ("Appended at right at left is - ")
print (DoubleEnded)

DoubleEnded.pop()
print ("Deleting from right - ")
print (DoubleEnded)

DoubleEnded.popleft()
print ("Deleting from left - ")
print (DoubleEnded)

Output

执行上述代码后,将生成以下结果 −

When the above code is executed, it produces the following result −

Appended at right -
deque(['Mon', 'Tue', 'Wed', 'Thu'])
Appended at right at left is -
deque(['Sun', 'Mon', 'Tue', 'Wed', 'Thu'])
Deleting from right -
deque(['Sun', 'Mon', 'Tue', 'Wed'])
Deleting from left -
deque(['Mon', 'Tue', 'Wed'])

Python - Advanced Linked list

我们在前一章中已经了解到了链表,在此链表中只能向前移动。在本教程中,我们将看到另一种链表,在此链表中可以向前和向后移动。这种链表称为双链表。以下是双链表的功能。

We have already seen Linked List in earlier chapter in which it is possible only to travel forward. In this chapter we see another type of linked list in which it is possible to travel both forward and backward. Such a linked list is called Doubly Linked List. Following is the features of doubly linked list.

  1. Doubly Linked List contains a link element called first and last.

  2. Each link carries a data field(s) and two link fields called next and prev.

  3. Each link is linked with its next link using its next link.

  4. Each link is linked with its previous link using its previous link.

  5. The last link carries a link as null to mark the end of the list.

Creating Doubly linked list

我们使用 Node 类创建双链表。现在,我们使用与在单链表中使用相同的方法,但是头部和下一个指针将用于适当的分配,以便在每个节点中创建两条链接,除了节点中显示的数据之外。

We create a Doubly Linked list by using the Node class. Now we use the same approach as used in the Singly Linked List but the head and next pointers will be used for proper assignation to create two links in each of the nodes in addition to the data present in the node.

Example

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

class doubly_linked_list:
   def __init__(self):
      self.head = None

# Adding data elements
   def push(self, NewVal):
      NewNode = Node(NewVal)
      NewNode.next = self.head
      if self.head is not None:
         self.head.prev = NewNode
      self.head = NewNode

# Print the Doubly Linked list
   def listprint(self, node):
      while (node is not None):
         print(node.data),
         last = node
         node = node.next

dllist = doubly_linked_list()
dllist.push(12)
dllist.push(8)
dllist.push(62)
dllist.listprint(dllist.head)

Output

执行上述代码后,将生成以下结果 −

When the above code is executed, it produces the following result −

62 8 12

Inserting into Doubly Linked List

此处,我们将看到如何使用以下程序将节点插入到双向链表中。该程序使用一个名为 insert 的方法,该方法在双链表头的第三个位置插入新节点。

Here, we are going to see how to insert a node to the Doubly Link List using the following program. The program uses a method named insert which inserts the new node at the third position from the head of the doubly linked list.

Example

# Create the Node class
class Node:
   def __init__(self, data):
      self.data = data
      self.next = None
      self.prev = None

# Create the doubly linked list
class doubly_linked_list:
   def __init__(self):
      self.head = None

# Define the push method to add elements
   def push(self, NewVal):
      NewNode = Node(NewVal)
      NewNode.next = self.head
      if self.head is not None:
         self.head.prev = NewNode
      self.head = NewNode

# Define the insert method to insert the element
   def insert(self, prev_node, NewVal):
      if prev_node is None:
         return
      NewNode = Node(NewVal)
      NewNode.next = prev_node.next
      prev_node.next = NewNode
      NewNode.prev = prev_node
      if NewNode.next is not None:
         NewNode.next.prev = NewNode

# Define the method to print the linked list
   def listprint(self, node):
      while (node is not None):
         print(node.data),
         last = node
         node = node.next

dllist = doubly_linked_list()
dllist.push(12)
dllist.push(8)
dllist.push(62)
dllist.insert(dllist.head.next, 13)
dllist.listprint(dllist.head)

Output

执行上述代码后,将生成以下结果 −

When the above code is executed, it produces the following result −

62  8  13  12

Appending to a Doubly linked list

向双向链表追加会将元素添加到末尾。

Appending to a doubly linked list will add the element at the end.

Example

# Create the node class
class Node:
   def __init__(self, data):
      self.data = data
      self.next = None
      self.prev = None
# Create the doubly linked list class
class doubly_linked_list:
   def __init__(self):
      self.head = None

# Define the push method to add elements at the begining
   def push(self, NewVal):
      NewNode = Node(NewVal)
      NewNode.next = self.head
      if self.head is not None:
         self.head.prev = NewNode
      self.head = NewNode

# Define the append method to add elements at the end
   def append(self, NewVal):
      NewNode = Node(NewVal)
      NewNode.next = None
      if self.head is None:
         NewNode.prev = None
         self.head = NewNode
         return
      last = self.head
      while (last.next is not None):
         last = last.next
      last.next = NewNode
      NewNode.prev = last
      return

# Define the method to print
   def listprint(self, node):
      while (node is not None):
         print(node.data),
         last = node
         node = node.next

dllist = doubly_linked_list()
dllist.push(12)
dllist.append(9)
dllist.push(8)
dllist.push(62)
dllist.append(45)
dllist.listprint(dllist.head)

Output

执行上述代码后,将生成以下结果 −

When the above code is executed, it produces the following result −

62 8 12 9 45

请注意追加操作中元素 9 和 45 的位置。

Please note the position of the elements 9 and 45 for the append operation.

Python - Hash Table

散列表是一种数据结构,其中数据元素的地址或索引值是由散列函数生成的。由于索引值充当数据值的键,因此访问数据会更快。换句话说,散列表存储键值对,但该键是通过散列函数生成的。

Hash tables are a type of data structure in which the address or the index value of the data element is generated from a hash function. That makes accessing the data faster as the index value behaves as a key for the data value. In other words Hash table stores key-value pairs but the key is generated through a hashing function.

因此,数据元素的搜索和插入功能会变得更快,因为键值本身将成为存储数据的数组的索引。

So the search and insertion function of a data element becomes much faster as the key values themselves become the index of the array which stores the data.

在 Python 中,字典数据类型表示散列表的实现。词典中的键满足以下要求。

In Python, the Dictionary data types represent the implementation of hash tables. The Keys in the dictionary satisfy the following requirements.

  1. The keys of the dictionary are hashable i.e. the are generated by hashing function which generates unique result for each unique value supplied to the hash function.

  2. The order of data elements in a dictionary is not fixed.

因此,我们看到使用字典数据类型实现散列表,如下所示。

So we see the implementation of hash table by using the dictionary data types as below.

Accessing Values in Dictionary

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

To access dictionary elements, you can use the familiar square brackets along with the key to obtain its value.

Example

# Declare a dictionary
dict = {'Name': 'Zara', 'Age': 7, 'Class': 'First'}

# Accessing the dictionary with its key
print ("dict['Name']: ", dict['Name'])
print ("dict['Age']: ", dict['Age'])

Output

执行上述代码后,将生成以下结果 −

When the above code is executed, it produces the following result −

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

Updating Dictionary

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

You can update a dictionary by adding a new entry or a key-value pair, modifying an existing entry, or deleting an existing entry as shown below in the simple example −

Example

# Declare a dictionary
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'])

Output

执行上述代码后,将生成以下结果 −

When the above code is executed, it produces the following result −

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

Delete Dictionary Elements

你可以删除单个词典元素或清除词典的全部内容。你也可以通过单个操作来删除整个词典。要明确删除整个词典,只需使用 del 语句。

You can either remove individual dictionary elements or clear the entire contents of a dictionary. You can also delete entire dictionary in a single operation.To explicitly remove an entire dictionary, just use the del statement.

Example

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'])

Output

这会产生以下结果。请注意,会引发异常,因为在 del dict 之后,词典就不再存在。

This produces the following result. Note that an exception is raised because after del dict dictionary does not exist anymore.

dict['Age']:  dict['Age']
dict['School']:  dict['School']

Python - Binary Tree

树表示由边连接的节点。它是一种非线性数据结构。它具有以下属性:

Tree represents the nodes connected by edges. It is a non-linear data structure. It has the following properties −

  1. One node is marked as Root node.

  2. Every node other than the root is associated with one parent node.

  3. Each node can have an arbiatry number of chid node.

我们通过使用前面讨论过的节点概念在 Python 中创建一个树数据结构。我们将一个节点指定为根节点,然后添加更多节点作为子节点。以下是创建根节点的程序。

We create a tree data structure in python by using the concept os node discussed earlier. We designate one node as root node and then add more nodes as child nodes. Below is program to create the root node.

Create Root

我们只创建一个 Node 类,并将一个值分配给节点。这将成为仅有一个根节点的树。

We just create a Node class and add assign a value to the node. This becomes tree with only a root node.

Example

class Node:
   def __init__(self, data):
      self.left = None
      self.right = None
      self.data = data
   def PrintTree(self):
      print(self.data)

root = Node(10)
root.PrintTree()

Output

执行上述代码后,将生成以下结果 −

When the above code is executed, it produces the following result −

10

Inserting into a Tree

为了插入树中,我们使用上面创建的相同 Node 类,并向其添加一个插入类。插入类将节点的值与父节点的值进行比较,并决定将其添加为左节点还是右节点。最后,使用 PrintTree 类来打印树。

To insert into a tree we use the same node class created above and add a insert class to it. The insert class compares the value of the node to the parent node and decides to add it as a left node or a right node. Finally the PrintTree class is used to print the tree.

Example

class Node:
   def __init__(self, data):
      self.left = None
      self.right = None
      self.data = data

   def insert(self, data):
# Compare the new value with the parent node
      if self.data:
         if data < self.data:
            if self.left is None:
               self.left = Node(data)
            else:
               self.left.insert(data)
         elif data > self.data:
               if self.right is None:
                  self.right = Node(data)
               else:
                  self.right.insert(data)
      else:
         self.data = data

# Print the tree
   def PrintTree(self):
      if self.left:
         self.left.PrintTree()
      print( self.data),
      if self.right:
         self.right.PrintTree()

# Use the insert method to add nodes
root = Node(12)
root.insert(6)
root.insert(14)
root.insert(3)
root.PrintTree()

Output

执行上述代码后,将生成以下结果 −

When the above code is executed, it produces the following result −

3 6 12 14

Traversing a Tree

可以通过决定一个顺序来访问每个节点来遍历树。我们可以清楚地看到,我们可以从一个节点开始,然后先访问左子树,再访问右子树。或者,我们也可以先访问右子树,再访问左子树。因此,这些树遍历方法有不同的名称。

The tree can be traversed by deciding on a sequence to visit each node. As we can clearly see we can start at a node then visit the left sub-tree first and right sub-tree next. Or we can also visit the right sub-tree first and left sub-tree next. Accordingly there are different names for these tree traversal methods.

Tree Traversal Algorithms

遍历是一个访问树的所有节点并可能也打印其值的过程。因为所有节点都通过边(链接)连接,所以我们总是从根(头)节点开始。也就是说,我们不能在树中随机访问一个节点。我们可以使用三种方式来遍历树。

Traversal is a process to visit all the nodes of a tree and may print their values too. Because, all nodes are connected via edges (links) we always start from the root (head) node. That is, we cannot randomly access a node in a tree. There are three ways which we use to traverse a tree.

  1. In-order Traversal

  2. Pre-order Traversal

  3. Post-order Traversal

In-order Traversal

在这种遍历方法中,首先访问左子树,然后访问根,最后访问右子树。我们应该始终记住,每个节点本身都可能表示一个子树。

In this traversal method, the left subtree is visited first, then the root and later the right sub-tree. We should always remember that every node may represent a subtree itself.

在下面的 Python 程序中,我们使用 Node 类来创建根节点以及左节点和右节点的占位符。然后,我们创建一个插入函数以将数据添加到树中。最后,通过创建空列表并首先添加左节点,然后添加根节点或父节点来实现中序遍历逻辑。

In the below python program, we use the Node class to create place holders for the root node as well as the left and right nodes. Then, we create an insert function to add data to the tree. Finally, the In-order traversal logic is implemented by creating an empty list and adding the left node first followed by the root or parent node.

最后,添加左节点以完成中序遍历。请注意,该过程将对每个子树重复,直到遍历所有节点。

At last the left node is added to complete the In-order traversal. Please note that this process is repeated for each sub-tree until all the nodes are traversed.

Example

class Node:
   def __init__(self, data):
      self.left = None
      self.right = None
      self.data = data
# Insert Node
   def insert(self, data):
      if self.data:
         if data < self.data:
            if self.left is None:
               self.left = Node(data)
            else:
               self.left.insert(data)
         else data > self.data:
            if self.right is None:
               self.right = Node(data)
            else:
               self.right.insert(data)
      else:
         self.data = data
# Print the Tree
   def PrintTree(self):
      if self.left:
         self.left.PrintTree()
      print( self.data),
      if self.right:
         self.right.PrintTree()
# Inorder traversal
# Left -> Root -> Right
   def inorderTraversal(self, root):
      res = []
      if root:
         res = self.inorderTraversal(root.left)
         res.append(root.data)
         res = res + self.inorderTraversal(root.right)
      return res
root = Node(27)
root.insert(14)
root.insert(35)
root.insert(10)
root.insert(19)
root.insert(31)
root.insert(42)
print(root.inorderTraversal(root))

Output

执行上述代码后,将生成以下结果 −

When the above code is executed, it produces the following result −

[10, 14, 19, 27, 31, 35, 42]

Pre-order Traversal

在这种遍历方法中,首先访问根节点,然后访问左子树,最后访问右子树。

In this traversal method, the root node is visited first, then the left subtree and finally the right subtree.

在下面的 Python 程序中,我们使用 Node 类来创建根节点以及左节点和右节点的占位符。然后,我们创建一个插入函数来向树中添加数据。最后,通过创建一个空列表并首先添加根节点,然后添加左节点,实现了先序遍历逻辑。

In the below python program, we use the Node class to create place holders for the root node as well as the left and right nodes. Then, we create an insert function to add data to the tree. Finally, the Pre-order traversal logic is implemented by creating an empty list and adding the root node first followed by the left node.

最后,添加右节点以完成先序遍历。请注意,此过程会重复执行,直到遍历完所有节点为止。

At last, the right node is added to complete the Pre-order traversal. Please note that, this process is repeated for each sub-tree until all the nodes are traversed.

Example

class Node:
   def __init__(self, data):
      self.left = None
      self.right = None
      self.data = data
# Insert Node
   def insert(self, data):
      if self.data:
         if data < self.data:
            if self.left is None:
               self.left = Node(data)
            else:
               self.left.insert(data)
         elif data > self.data:
            if self.right is None:
               self.right = Node(data)
            else:
               self.right.insert(data)
         else:
            self.data = data
# Print the Tree
   def PrintTree(self):
      if self.left:
         self.left.PrintTree()
      print( self.data),
      if self.right:
         self.right.PrintTree()
# Preorder traversal
# Root -> Left ->Right
   def PreorderTraversal(self, root):
      res = []
      if root:
         res.append(root.data)
         res = res + self.PreorderTraversal(root.left)
         res = res + self.PreorderTraversal(root.right)
      return res
root = Node(27)
root.insert(14)
root.insert(35)
root.insert(10)
root.insert(19)
root.insert(31)
root.insert(42)
print(root.PreorderTraversal(root))

Output

执行上述代码后,将生成以下结果 −

When the above code is executed, it produces the following result −

[27, 14, 10, 19, 35, 31, 42]

Post-order Traversal

在此遍历方法中,根节点最后访问,因此得名。首先,我们遍历左子树,然后遍历右子树,最后遍历根节点。

In this traversal method, the root node is visited last, hence the name. First, we traverse the left subtree, then the right subtree and finally the root node.

在下面的 Python 程序中,我们使用 Node 类来创建根节点以及左节点和右节点的占位符。然后,我们创建一个插入函数来向树中添加数据。最后,通过创建一个空列表并先添加左节点,然后添加右节点,实现了后序遍历逻辑。

In the below python program, we use the Node class to create place holders for the root node as well as the left and right nodes. Then, we create an insert function to add data to the tree. Finally, the Post-order traversal logic is implemented by creating an empty list and adding the left node first followed by the right node.

最后,添加根节点或父节点以完成后序遍历。请注意,此过程会重复执行,直到遍历完所有节点为止。

At last the root or parent node is added to complete the Post-order traversal. Please note that, this process is repeated for each sub-tree until all the nodes are traversed.

Example

class Node:
   def __init__(self, data):
      self.left = None
      self.right = None
      self.data = data
# Insert Node
   def insert(self, data):
      if self.data:
         if data < self.data:
            if self.left is None:
               self.left = Node(data)
            else:
               self.left.insert(data)
         else if data > self.data:
            if self.right is None:
               self.right = Node(data)
            else:

               self.right.insert(data)
      else:
         self.data = data
# Print the Tree
   def PrintTree(self):
      if self.left:
         self.left.PrintTree()
print( self.data),
if self.right:
self.right.PrintTree()
# Postorder traversal
# Left ->Right -> Root
def PostorderTraversal(self, root):
res = []
if root:
res = self.PostorderTraversal(root.left)
res = res + self.PostorderTraversal(root.right)
res.append(root.data)
return res
root = Node(27)
root.insert(14)
root.insert(35)
root.insert(10)
root.insert(19)
root.insert(31)
root.insert(42)
print(root.PostorderTraversal(root))

Output

执行上述代码后,将生成以下结果 −

When the above code is executed, it produces the following result −

[10, 19, 14, 31, 42, 35, 27]

Python - Search Tree

二叉搜索树 (BST) 是一棵树,其中所有节点都遵循以下属性。节点的左子树的键小于或等于其父节点的键。节点的右子树的键大于其父节点的键。因此,BST 将其所有子树分成两个部分;左子树和右子树

A Binary Search Tree (BST) is a tree in which all the nodes follow the below-mentioned properties.The left sub-tree of a node has a key less than or equal to its parent node’s key.The right sub-tree of a node has a key greater than to its parent node’s key.Thus, BST divides all its sub-trees into two segments; the left sub-tree and the right sub-tree

left_subtree (keys)  ≤  node (key)  ≤  right_subtree (keys)

Search for a value in a B-tree

在树中搜索值涉及将传入值与退出节点的值进行比较。在这里,我们也从左到右遍历节点,然后最终遍历父节点。如果搜索到的值与任何退出值不匹配,则我们返回找不到的消息,否则返回找到的消息。

Searching for a value in a tree involves comparing the incoming value with the value exiting nodes. Here also we traverse the nodes from left to right and then finally with the parent. If the searched for value does not match any of the exiting value, then we return not found message, or else the found message is returned.

Example

class Node:
   def __init__(self, data):
      self.left = None
      self.right = None
      self.data = data
# Insert method to create nodes
   def insert(self, data):
      if self.data:
         if data < self.data:
            if self.left is None:
               self.left = Node(data)
            else:
               self.left.insert(data)
            else data > self.data:
               if self.right is None:
                  self.right = Node(data)
               else:
                  self.right.insert(data)
         else:
            self.data = data
# findval method to compare the value with nodes
   def findval(self, lkpval):
      if lkpval < self.data:
         if self.left is None:
            return str(lkpval)+" Not Found"
         return self.left.findval(lkpval)
       else if lkpval > self.data:
            if self.right is None:
               return str(lkpval)+" Not Found"
            return self.right.findval(lkpval)
        else:
            print(str(self.data) + ' is found')
# Print the tree
   def PrintTree(self):
      if self.left:
         self.left.PrintTree()
      print( self.data),
      if self.right:
         self.right.PrintTree()
root = Node(12)
root.insert(6)
root.insert(14)
root.insert(3)
print(root.findval(7))
print(root.findval(14))

Output

执行上述代码后,将生成以下结果 −

When the above code is executed, it produces the following result −

7 Not Found
14 is found

Python - Heaps

堆是一种特殊的树结构,其中每个父节点都小于或等于其子节点。然后将其称为最小堆。如果每个父节点都大于或等于其子节点,则将其称为最大堆。在实现优先级队列时它非常有用,其中赋予具有较高权重的队列项在处理中更高的优先级。

Heap is a special tree structure in which each parent node is less than or equal to its child node. Then it is called a Min Heap. If each parent node is greater than or equal to its child node then it is called a max heap. It is very useful is implementing priority queues where the queue item with higher weightage is given more priority in processing.

关于堆的详细讨论可在我们的网站上获得这里。如果你不熟悉堆数据结构,请先学习它。在本章中,我们将看到使用 Python 实现堆数据结构。

A detailed discussion on heaps is available in our website here. Please study it first if you are new to heap data structure. In this chapter we will see the implementation of heap data structure using python.

Create a Heap

通过使用名为 heapq 的 Python 内置库来创建堆。此库具有执行堆数据结构上各种操作的相关函数。以下是这些函数的列表。

A heap is created by using python’s inbuilt library named heapq. This library has the relevant functions to carry out various operations on heap data structure. Below is a list of these functions.

  1. heapify − This function converts a regular list to a heap. In the resulting heap the smallest element gets pushed to the index position 0. But rest of the data elements are not necessarily sorted.

  2. heappush − This function adds an element to the heap without altering the current heap.

  3. heappop − This function returns the smallest data element from the heap.

  4. heapreplace − This function replaces the smallest data element with a new value supplied in the function.

Creating a Heap

只需使用带堆化函数的元素列表就可以创建堆。以下示例中,我们提供一个元素列表,堆化函数重新排列元素,将最小元素放置在第一位。

A heap is created by simply using a list of elements with the heapify function. In the below example we supply a list of elements and the heapify function rearranges the elements bringing the smallest element to the first position.

Example

import heapq

H = [21,1,45,78,3,5]
# Use heapify to rearrange the elements
heapq.heapify(H)
print(H)

Output

执行上述代码后,将生成以下结果 −

When the above code is executed, it produces the following result −

[1, 3, 5, 78, 21, 45]

Inserting into heap

向堆中插入数据元素时总是将元素添加到最后一个索引位置。但只在该元素的数值最小的情况下,才能再次应用堆化函数以将新添加的元素移动到第一索引位置。以下示例中,我们插入数字 8。

Inserting a data element to a heap always adds the element at the last index. But you can apply heapify function again to bring the newly added element to the first index only if it smallest in value. In the below example we insert the number 8.

Example

import heapq

H = [21,1,45,78,3,5]
# Covert to a heap
heapq.heapify(H)
print(H)

# Add element
heapq.heappush(H,8)
print(H)

Output

执行上述代码后,将生成以下结果 −

When the above code is executed, it produces the following result −

[1, 3, 5, 78, 21, 45]
[1, 3, 5, 78, 21, 45, 8]

Removing from heap

可以使用此函数移除第一个索引位置处的元素。以下示例中,该函数总是将索引位置为 1 处的元素移除。

You can remove the element at first index by using this function. In the below example the function will always remove the element at the index position 1.

Example

import heapq

H = [21,1,45,78,3,5]
# Create the heap

heapq.heapify(H)
print(H)

# Remove element from the heap
heapq.heappop(H)

print(H)

Output

执行上述代码后,将生成以下结果 −

When the above code is executed, it produces the following result −

[1, 3, 5, 78, 21, 45]
[3, 21, 5, 78, 45]

Replacing in a Heap

堆替换函数始终移除堆中最小的元素,并将新进入的元素插入某个未按任何顺序固定的位置。

The heap replace function always removes the smallest element of the heap and inserts the new incoming element at some place not fixed by any order.

Example

import heapq

H = [21,1,45,78,3,5]
# Create the heap

heapq.heapify(H)
print(H)

# Replace an element
heapq.heapreplace(H,6)
print(H)

Output

执行上述代码后,将生成以下结果 −

When the above code is executed, it produces the following result −

[1, 3, 5, 78, 21, 45]
[3, 6, 5, 78, 21, 45]

Python - Graphs

图是对一组对象的图形化表示,其中某些对象对通过链接连接。互连的对象由称为顶点的点表示,连接顶点的链接称为边。与图相关的各种术语和功能在本教程中有详细说明。

A graph is a pictorial representation of a set of objects where some pairs of objects are connected by links. The interconnected objects are represented by points termed as vertices, and the links that connect the vertices are called edges. The various terms and functionalities associated with a graph is described in great detail in our tutorial here.

在本章中,我们将看到如何使用 Python 程序创建图,并向其中添加各种数据元素。以下是我们在图上进行的基本操作。

In this chapter we are going to see how to create a graph and add various data elements to it using a python program. Following are the basic operations we perform on graphs.

  1. Display graph vertices

  2. Display graph edges

  3. Add a vertex

  4. Add an edge

  5. Creating a graph

可以使用 Python 字典数据类型轻松呈现图。我们将顶点表示为字典的键,并将称为边的顶点之间的连接表示为字典中的值。

A graph can be easily presented using the python dictionary data types. We represent the vertices as the keys of the dictionary and the connection between the vertices also called edges as the values in the dictionary.

请看下面的图表 −

Take a look at the following graph −

graph basics

在上图中,

In the above graph,

V = {a, b, c, d, e}
E = {ab, ac, bd, cd, de}

Example

我们可以将此图表示为以下 Python 程序 −

We can present this graph in a python program as below −

# Create the dictionary with graph elements
graph = {
   "a" : ["b","c"],
   "b" : ["a", "d"],
   "c" : ["a", "d"],
   "d" : ["e"],
   "e" : ["d"]
}
# Print the graph
print(graph)

Output

执行上述代码后,将生成以下结果 −

When the above code is executed, it produces the following result −

{'c': ['a', 'd'], 'a': ['b', 'c'], 'e': ['d'], 'd': ['e'], 'b': ['a', 'd']}

Display graph vertices

要显示图顶点,我们只需找到图字典的键。我们使用 keys() 方法。

To display the graph vertices we simple find the keys of the graph dictionary. We use the keys() method.

class graph:
   def __init__(self,gdict=None):
      if gdict is None:
         gdict = []
      self.gdict = gdict
# Get the keys of the dictionary
   def getVertices(self):
      return list(self.gdict.keys())
# Create the dictionary with graph elements
graph_elements = {
   "a" : ["b","c"],
   "b" : ["a", "d"],
   "c" : ["a", "d"],
   "d" : ["e"],
   "e" : ["d"]
}
g = graph(graph_elements)
print(g.getVertices())

Output

执行上述代码后,将生成以下结果 −

When the above code is executed, it produces the following result −

['d', 'b', 'e', 'c', 'a']

Display graph edges

找到图边比找到顶点要困难一些,因为我们必须找到每对之间有边的顶点的各个对。因此,我们创建一个空的边列表,然后遍历与每个顶点关联的边值。我们将形成一个包含从顶点找到的不同组边的列表。

Finding the graph edges is little tricker than the vertices as we have to find each of the pairs of vertices which have an edge in between them. So we create an empty list of edges then iterate through the edge values associated with each of the vertices. A list is formed containing the distinct group of edges found from the vertices.

class graph:
   def __init__(self,gdict=None):
      if gdict is None:
         gdict = {}
      self.gdict = gdict

   def edges(self):
      return self.findedges()
# Find the distinct list of edges
   def findedges(self):
      edgename = []
      for vrtx in self.gdict:
         for nxtvrtx in self.gdict[vrtx]:
            if {nxtvrtx, vrtx} not in edgename:
               edgename.append({vrtx, nxtvrtx})
      return edgename
# Create the dictionary with graph elements
graph_elements = {
   "a" : ["b","c"],
   "b" : ["a", "d"],
   "c" : ["a", "d"],
   "d" : ["e"],
   "e" : ["d"]
}
g = graph(graph_elements)
print(g.edges())

Output

执行上述代码后,将生成以下结果 −

When the above code is executed, it produces the following result −

[{'b', 'a'}, {'b', 'd'}, {'e', 'd'}, {'a', 'c'}, {'c', 'd'}]

Adding a vertex

添加顶点非常直接,我们在图字典中添加另一个额外的键即可。

Adding a vertex is straight forward where we add another additional key to the graph dictionary.

Example

class graph:
   def __init__(self,gdict=None):
      if gdict is None:
         gdict = {}
      self.gdict = gdict
   def getVertices(self):
      return list(self.gdict.keys())
# Add the vertex as a key
   def addVertex(self, vrtx):
      if vrtx not in self.gdict:
         self.gdict[vrtx] = []
# Create the dictionary with graph elements
graph_elements = {
   "a" : ["b","c"],
   "b" : ["a", "d"],
   "c" : ["a", "d"],
   "d" : ["e"],
   "e" : ["d"]
}
g = graph(graph_elements)
g.addVertex("f")
print(g.getVertices())

Output

执行上述代码后,将生成以下结果 −

When the above code is executed, it produces the following result −

['a', 'b', 'c', 'd', 'e','f']

Adding an edge

向现有图添加边涉及将新顶点视为元组,并验证该边是否已经存在。如果不存在,则添加该边。

Adding an edge to an existing graph involves treating the new vertex as a tuple and validating if the edge is already present. If not then the edge is added.

class graph:
   def __init__(self,gdict=None):
      if gdict is None:
         gdict = {}
      self.gdict = gdict
   def edges(self):
      return self.findedges()
# Add the new edge
   def AddEdge(self, edge):
      edge = set(edge)
      (vrtx1, vrtx2) = tuple(edge)
      if vrtx1 in self.gdict:
         self.gdict[vrtx1].append(vrtx2)
      else:
         self.gdict[vrtx1] = [vrtx2]
# List the edge names
   def findedges(self):
      edgename = []
      for vrtx in self.gdict:
         for nxtvrtx in self.gdict[vrtx]:
            if {nxtvrtx, vrtx} not in edgename:
               edgename.append({vrtx, nxtvrtx})
        return edgename
# Create the dictionary with graph elements
graph_elements = {
   "a" : ["b","c"],
   "b" : ["a", "d"],
   "c" : ["a", "d"],
   "d" : ["e"],
   "e" : ["d"]
}
g = graph(graph_elements)
g.AddEdge({'a','e'})
g.AddEdge({'a','c'})
print(g.edges())

Output

执行上述代码后,将生成以下结果 −

When the above code is executed, it produces the following result −

[{'e', 'd'}, {'b', 'a'}, {'b', 'd'}, {'a', 'c'}, {'a', 'e'}, {'c', 'd'}]

Python - Algorithm Design

算法是一个循序渐进的过程,它定义了一组按特定顺序执行的指令,以获得所需的输出。算法通常独立于底层语言创建,即算法可以在不止一种编程语言中实现。

Algorithm is a step-by-step procedure, which defines a set of instructions to be executed in a certain order to get the desired output. Algorithms are generally created independent of underlying languages, i.e. an algorithm can be implemented in more than one programming language.

从数据结构的角度来看,以下是一些重要的算法类别 -

From the data structure point of view, following are some important categories of algorithms −

  1. Search − Algorithm to search an item in a data structure.

  2. Sort − Algorithm to sort items in a certain order.

  3. Insert − Algorithm to insert item in a data structure.

  4. Update − Algorithm to update an existing item in a data structure.

  5. Delete − Algorithm to delete an existing item from a data structure.

Characteristics of an Algorithm

并非所有程序都可以称为算法。算法应具有以下特征 -

Not all procedures can be called an algorithm. An algorithm should have the following characteristics −

  1. Unambiguous − Algorithm should be clear and unambiguous. Each of its steps (or phases), and their inputs/outputs should be clear and must lead to only one meaning.

  2. Input − An algorithm should have 0 or more well-defined inputs.

  3. Output − An algorithm should have 1 or more well-defined outputs, and should match the desired output.

  4. Finiteness − Algorithms must terminate after a finite number of steps.

  5. Feasibility − Should be feasible with the available resources.

  6. Independent − An algorithm should have step-by-step directions, which should be independent of any programming code.

How to Write an Algorithm?

对于编写算法,没有明确定义的标准。相反,它取决于问题和资源。算法永远不会被编写来支持特定的编程代码。

There are no well-defined standards for writing algorithms. Rather, it is problem and resource dependent. Algorithms are never written to support a particular programming code.

正如我们所知,所有编程语言都共享基础代码构造,如循环(do、for、while)、流程控制(if-else)等。这些通用构造可用于编写算法。

As we know that all programming languages share basic code constructs like loops (do, for, while), flow-control (if-else), etc. These common constructs can be used to write an algorithm.

我们按部就班编写算法,但并不总是如此。算法编写是一个过程,在问题域定义明确后执行。也就是说,我们应该了解问题域,并针对该问题域设计解决方案。

We write algorithms in a step-by-step manner, but it is not always the case. Algorithm writing is a process and is executed after the problem domain is well-defined. That is, we should know the problem domain, for which we are designing a solution.

Example

我们尝试通过示例来学习算法编写。

Let’s try to learn algorithm-writing by using an example.

  1. Problem − Design an algorithm to add two numbers and display the result.

step 1 − 开始

step 1 − START

step 2 − 声明三个整数 abc

step 2 − declare three integers a, b & c

step 3 − 定义 ab 的值

step 3 − define values of a & b

step 4 − 对 ab 的值进行加法

step 4 − add values of a & b

step 5 − 将步骤 4 的输出存储到 c

step 5 − store output of step 4 to c

step 6 − 打印 c

step 6 − print c

step 7 − 结束

step 7 − STOP

算法告诉程序员如何对程序进行编码。或者,算法可以写成 −

Algorithms tell the programmers how to code the program. Alternatively, the algorithm can be written as −

step 1 − 开始加法

step 1 − START ADD

step 2 − 获取 ab 的值

step 2 − get values of a & b

step 3 − c ← a + b

step 3 − c ← a + b

step 4 − 显示 c

step 4 − display c

step 5 − 结束

step 5 − STOP

在算法的设计和分析中,通常使用第二种方法来描述算法。这使得分析员能够轻松地分析算法,而忽略所有不需要的定义。他可以观察正在使用什么操作以及流程如何进行。

In design and analysis of algorithms, usually the second method is used to describe an algorithm. It makes it easy for the analyst to analyze the algorithm ignoring all unwanted definitions. He can observe what operations are being used and how the process is flowing.

编写 step numbers 是可选的。

Writing step numbers, is optional.

我们设计了一个算法来解决给定问题。一个问题可以用多种方法解决。

We design an algorithm to get a solution of a given problem. A problem can be solved in more than one ways.

problem solutions

因此,可以为给定的问题导出许多求解算法。下一步是分析那些建议的求解算法并执行最适合的解决方案。

Hence, many solution algorithms can be derived for a given problem. The next step is to analyze those proposed solution algorithms and implement the best suitable solution.

Python - Divide and Conquer

在分治法中,手头的问题被划分为更小的子问题,然后独立解决每个问题。当我们继续将子问题划分为更小的子问题时,最终可能会达到无法进一步划分的阶段。解决这些“原子”的最小可能子问题(部分)。所有子问题的解最终都会合并,以获得原始问题的解。

In divide and conquer approach, the problem in hand, is divided into smaller sub-problems and then each problem is solved independently. When we keep on dividing the subproblems into even smaller sub-problems, we may eventually reach a stage where no more division is possible. Those "atomic" smallest possible sub-problem (fractions) are solved. The solution of all sub-problems is finally merged in order to obtain the solution of an original problem.

divide and conquer

从广义上讲,我们可以通过三个步骤理解 @ {s0} 方法。

Broadly, we can understand divide-and-conquer approach in a three-step process.

Divide/Break

此步骤涉及将问题分解为更小的子问题。子问题应表示原始问题的一部分。此步骤通常采用递归方法来划分问题,直到无法进一步划分子问题。在此阶段,子问题本质上变成了原子,但仍然表示实际问题的一部分。

This step involves breaking the problem into smaller sub-problems. Sub-problems should represent a part of the original problem. This step generally takes a recursive approach to divide the problem until no sub-problem is further divisible. At this stage, sub-problems become atomic in nature but still represent some part of the actual problem.

Conquer/Solve

此步骤接收许多较小的子问题以求解。通常,在此级别上,问题被认为自己“已解决”。

This step receives a lot of smaller sub-problems to be solved. Generally, at this level, the problems are considered 'solved' on their own.

Merge/Combine

当较小的子问题得到解决时,此阶段将它们循环组合,直至形成原问题的解决方案。这种算法方法按递归方式工作,而且拆分和合并步骤非常接近,看上去它们好像是一样的。

When the smaller sub-problems are solved, this stage recursively combines them until they formulate a solution of the original problem. This algorithmic approach works recursively and conquer &s; merge steps works so close that they appear as one.

Examples

下面的程序是 divide-and-conquer 编程方法的一个示例,其中使用 Python 实现了二分搜索。

The following program is an example of divide-and-conquer programming approach where the binary search is implemented using python.

Binary Search implementation

在二分搜索中,我们选取一个元素的有序列表,并开始在该列表的中间位置查找元素。如果搜索值与列表中的中间值匹配,则完成搜索。否则,我们将根据被搜索项目的值选取列表的右半部分或左半部分,从而消除列表中一半的元素。

In binary search we take a sorted list of elements and start looking for an element at the middle of the list. If the search value matches with the middle value in the list we complete the search. Otherwise we eleminate half of the list of elements by choosing whether to procees with the right or left half of the list depending on the value of the item searched.

这是可行的,因为列表是有序的,并且它比线性搜索快得多。在这里,我们根据被搜索项目的值选取列表的右半部分或左半部分,从而分离给定的列表并征服它。我们将重复这种做法,直到找到该元素,或推断出它不在列表中。

This is possible as the list is sorted and it is much quicker than linear search.Here we divide the given list and conquer by choosing the proper half of the list. We repeat this approcah till we find the element or conclude about it’s absence in the list.

Example

def bsearch(list, val):
   list_size = len(list) - 1
   idx0 = 0
   idxn = list_size
# Find the middle most value
   while idx0 <= idxn:
      midval = (idx0 + idxn)// 2
      if list[midval] == val:
         return midval
# Compare the value the middle most value
   if val > list[midval]:
      idx0 = midval + 1
   else:
      idxn = midval - 1
   if idx0 > idxn:
      return None
# Initialize the sorted list
list = [2,7,19,34,53,72]

# Print the search result
print(bsearch(list,72))
print(bsearch(list,11))

Output

执行上述代码后,将生成以下结果 −

When the above code is executed, it produces the following result −

5
None

Python - Recursion

递归允许函数调用自身。一段固定代码步骤会不断地针对新值执行。我们还必须设定用于确定递归调用何时结束的标准。在下面的示例中,我们将看到二分搜索的递归方法。我们选取一个有序列表,并将其索引范围作为输入提供给递归函数。

Recursion allows a function to call itself. Fixed steps of code get executed again and again for new values. We also have to set criteria for deciding when the recursive call ends. In the below example we see a recursive approach to the binary search. We take a sorted list and give its index range as input to the recursive function.

Binary Search using Recursion

我们使用 Python 实现了二分搜索算法,如下所示。我们使用一个有序项列表,并设计了一个递归函数,以列表以及起始索引和结束索引作为输入。然后,二分搜索函数将不断调用自己,直到找到被搜索的项目,或推断出它不在列表中。

We implement the algorithm of binary search using python as shown below. We use an ordered list of items and design a recursive function to take in the list along with starting and ending index as input. Then, the binary search function calls itself till find the searched item or concludes about its absence in the list.

Example

def bsearch(list, idx0, idxn, val):
   if (idxn < idx0):
      return None
   else:
      midval = idx0 + ((idxn - idx0) // 2)
# Compare the search item with middle most value
   if list[midval] > val:
      return bsearch(list, idx0, midval-1,val)
   else if list[midval] < val:
      return bsearch(list, midval+1, idxn, val)
   else:
      return midval
list = [8,11,24,56,88,131]
print(bsearch(list, 0, 5, 24))
print(bsearch(list, 0, 5, 51))

Output

执行上述代码后,将生成以下结果 −

When the above code is executed, it produces the following result −

2
None

Python - Backtracking

回溯是一种递归形式。但它仅涉及从任何可能中选择一个选项。我们首先选择一个选项,然后从中进行回溯,如果我们达到一个得出此特定选项无法给出所需解决方案的状态。我们通过遍历每个可用选项来重复这些步骤,直到找到所需解决方案。

Backtracking is a form of recursion. But it involves choosing only option out of any possibilities. We begin by choosing an option and backtrack from it, if we reach a state where we conclude that this specific option does not give the required solution. We repeat these steps by going across each available option until we get the desired solution.

下面是查找给定一组字母的所有可能排列顺序的示例。当我们选择一对时,我们会应用回溯来验证是否已经创建了该准确对。如果尚未创建,则将对添加到答案列表中,否则将忽略。

Below is an example of finding all possible order of arrangements of a given set of letters. When we choose a pair we apply backtracking to verify if that exact pair has already been created or not. If not already created, the pair is added to the answer list else it is ignored.

Example

def permute(list, s):
   if list == 1:
      return s
   else:
      return [
         y + x
         for y in permute(1, s)
         for x in permute(list - 1, s)
      ]
print(permute(1, ["a","b","c"]))
print(permute(2, ["a","b","c"]))

Output

执行上述代码后,将生成以下结果 −

When the above code is executed, it produces the following result −

['a', 'b', 'c']
['aa', 'ab', 'ac', 'ba', 'bb', 'bc', 'ca', 'cb', 'cc']

Python - Sorting Algorithms

排序是指按照特定格式排列数据。排序算法规定了以特定顺序排列数据的方式。最常见的顺序是按数字或词法顺序。

Sorting refers to arranging data in a particular format. Sorting algorithm specifies the way to arrange data in a particular order. Most common orders are in numerical or lexicographical order.

排序的重要性在于,如果数据以有序的方式存储,则可以将数据搜索优化到非常高的级别。排序还用于以更易读的格式表示数据。下面,我们看到在 python 中使用了五种这样的排序实现。

The importance of sorting lies in the fact that data searching can be optimized to a very high level, if data is stored in a sorted manner. Sorting is also used to represent data in more readable formats. Below we see five such implementations of sorting in python.

  1. Bubble Sort

  2. Merge Sort

  3. Insertion Sort

  4. Shell Sort

  5. Selection Sort

Bubble Sort

这是一种基于比较的算法,其中比较每对相邻的元素,如果它们不在顺序中,则交换元素。

It is a comparison-based algorithm in which each pair of adjacent elements is compared and the elements are swapped if they are not in order.

Example

def bubblesort(list):

# Swap the elements to arrange in order
   for iter_num in range(len(list)-1,0,-1):
      for idx in range(iter_num):
         if list[idx]>list[idx+1]:
            temp = list[idx]
            list[idx] = list[idx+1]
            list[idx+1] = temp
list = [19,2,31,45,6,11,121,27]
bubblesort(list)
print(list)

Output

执行上述代码后,将生成以下结果 −

When the above code is executed, it produces the following result −

[2, 6, 11, 19, 27, 31, 45, 121]

Merge Sort

归并排序先将数组分成相等的两个部分,然后按顺序合并它们。

Merge sort first divides the array into equal halves and then combines them in a sorted manner.

Example

def merge_sort(unsorted_list):
   if len(unsorted_list) <= 1:
      return unsorted_list
# Find the middle point and devide it
   middle = len(unsorted_list) // 2
   left_list = unsorted_list[:middle]
   right_list = unsorted_list[middle:]

   left_list = merge_sort(left_list)
   right_list = merge_sort(right_list)
   return list(merge(left_list, right_list))

# Merge the sorted halves
def merge(left_half,right_half):
   res = []
   while len(left_half) != 0 and len(right_half) != 0:
      if left_half[0] < right_half[0]:
         res.append(left_half[0])
         left_half.remove(left_half[0])
      else:
         res.append(right_half[0])
         right_half.remove(right_half[0])
   if len(left_half) == 0:
      res = res + right_half
   else:
      res = res + left_half
   return res
unsorted_list = [64, 34, 25, 12, 22, 11, 90]
print(merge_sort(unsorted_list))

Output

执行上述代码后,将生成以下结果 −

When the above code is executed, it produces the following result −

[11, 12, 22, 25, 34, 64, 90]

Insertion Sort

插入排序涉及在已排序列表中找到给定元素的正确位置。因此,在开始时,我们比较前两个元素并通过比较对它们进行排序。然后,我们挑选第三个元素,并在前两个已排序元素中找到其合适的位置。通过这种方式,我们将逐渐向已排序列表添加更多元素,方法是将它们放在正确的位置。

Insertion sort involves finding the right place for a given element in a sorted list. So in beginning we compare the first two elements and sort them by comparing them. Then we pick the third element and find its proper position among the previous two sorted elements. This way we gradually go on adding more elements to the already sorted list by putting them in their proper position.

Example

def insertion_sort(InputList):
   for i in range(1, len(InputList)):
      j = i-1
      nxt_element = InputList[i]
# Compare the current element with next one
   while (InputList[j] > nxt_element) and (j >= 0):
      InputList[j+1] = InputList[j]
      j=j-1
   InputList[j+1] = nxt_element
list = [19,2,31,45,30,11,121,27]
insertion_sort(list)
print(list)

Output

执行上述代码后,将生成以下结果 −

When the above code is executed, it produces the following result −

[19, 2, 31, 45, 30, 11, 27, 121]

Shell Sort

希尔排序涉及对远离彼此的元素进行排序。我们对给定列表中的一个较大的子列表进行排序,并不断减小该列表的大小,直到所有元素都按顺序排列。下面的程序通过将其等于列表大小长度的一半来找到差距,然后开始对其中的所有元素进行排序。然后,我们不断重置差距,直到整个列表按顺序排列。

Shell Sort involves sorting elements which are away from each other. We sort a large sublist of a given list and go on reducing the size of the list until all elements are sorted. The below program finds the gap by equating it to half of the length of the list size and then starts sorting all elements in it. Then we keep resetting the gap until the entire list is sorted.

Example

def shellSort(input_list):
   gap = len(input_list) // 2
   while gap > 0:
      for i in range(gap, len(input_list)):
         temp = input_list[i]
         j = i
# Sort the sub list for this gap
   while j >= gap and input_list[j - gap] > temp:
      input_list[j] = input_list[j - gap]
      j = j-gap
      input_list[j] = temp
# Reduce the gap for the next element
   gap = gap//2
list = [19,2,31,45,30,11,121,27]
shellSort(list)
print(list)

Output

执行上述代码后,将生成以下结果 −

When the above code is executed, it produces the following result −

[2, 11, 19, 27, 30, 31, 45, 121]

Selection Sort

在选择排序中,我们首先找到给定列表中的最小值并将其移动到已排序列表中。然后,我们对未排序列表中剩余的每个元素重复此过程。进入已排序列表的下一个元素与现有元素进行比较,并将其放置在正确的位置。因此,最后未排序列表中的所有元素都按顺序排列。

In selection sort we start by finding the minimum value in a given list and move it to a sorted list. Then we repeat the process for each of the remaining elements in the unsorted list. The next element entering the sorted list is compared with the existing elements and placed at its correct position.So, at the end all the elements from the unsorted list are sorted.

Example

def selection_sort(input_list):
   for idx in range(len(input_list)):
      min_idx = idx
      for j in range( idx +1, len(input_list)):
         if input_list[min_idx] > input_list[j]:
            min_idx = j
# Swap the minimum value with the compared value
   input_list[idx], input_list[min_idx] = input_list[min_idx], input_list[idx]
l = [19,2,31,45,30,11,121,27]
selection_sort(l)
print(l)

Output

执行上述代码后,将生成以下结果 −

When the above code is executed, it produces the following result −

[19, 2, 31, 45, 30, 11, 121, 27]

Python - Searching Algorithms

在不同的数据结构中存储数据时,搜索是一个非常基本的必要操作。最简单的方法是对数据结构中的每个元素进行遍历,并将其与要搜索的值进行匹配。这称为线性搜索。它效率低下,使用较少,但是为它创建程序可以了解如何实现一些高级搜索算法。

Searching is a very basic necessity when you store data in different data structures. The simplest approach is to go across every element in the data structure and match it with the value you are searching for.This is known as Linear search. It is inefficient and rarely used, but creating a program for it gives an idea about how we can implement some advanced search algorithms.

在此类搜索中,对所有项一个接一个地进行顺序搜索。检查每个项,如果找到匹配项,则返回该特定项,否则搜索继续进行,直到数据结构结束。

In this type of search, a sequential search is made over all items one by one. Every item is checked and if a match is found then that particular item is returned, otherwise the search continues till the end of the data structure.

Example

def linear_search(values, search_for):
   search_at = 0
   search_res = False
# Match the value with each data element
   while search_at < len(values) and search_res is False:
      if values[search_at] == search_for:
         search_res = True
      else:
         search_at = search_at + 1
   return search_res
l = [64, 34, 25, 12, 22, 11, 90]
print(linear_search(l, 12))
print(linear_search(l, 91))

Output

执行上述代码后,将生成以下结果 −

When the above code is executed, it produces the following result −

True
False

此搜索算法根据所需值的探测位置工作。为使此算法正常工作,数据集合应以排序形式分布,并且分布均匀。最初,探测位置是集合中最中间项的位置。如果发生匹配,则返回该项的索引。如果中间项大于该项,则在中间项右边的子数组中再次计算探测位置。否则,在中间项左边的子数组中搜索该项。此过程也会在子数组上继续,直到子数组的大小变为零。

This search algorithm works on the probing position of the required value. For this algorithm to work properly, the data collection should be in a sorted form and equally distributed.Initially, the probe position is the position of the middle most item of the collection.If a match occurs, then the index of the item is returned.If the middle item is greater than the item, then the probe position is again calculated in the sub-array to the right of the middle item. Otherwise, the item is searched in the subarray to the left of the middle item. This process continues on the sub-array as well until the size of subarray reduces to zero.

Example

有一个具体公式来计算中间位置,该公式在下面的程序中指示−

There is a specific formula to calculate the middle position which is indicated in the program below −

def intpolsearch(values,x ):
   idx0 = 0
   idxn = (len(values) - 1)
   while idx0 <= idxn and x >= values[idx0] and x <= values[idxn]:
# Find the mid point
	mid = idx0 +\
      int(((float(idxn - idx0)/( values[idxn] - values[idx0]))
      * ( x - values[idx0])))
# Compare the value at mid point with search value
   if values[mid] == x:
      return "Found "+str(x)+" at index "+str(mid)
   if values[mid] < x:
      idx0 = mid + 1
   return "Searched element not in the list"

l = [2, 6, 11, 19, 27, 31, 45, 121]
print(intpolsearch(l, 2))

Output

执行上述代码后,将生成以下结果 −

When the above code is executed, it produces the following result −

Found 2 at index 0

Python - Graph Algorithms

图是非常有用的数据结构,可用于解决许多重要的数学难题。例如,计算机网络拓扑或分析化学化合物的分子结构。它们还用于城市交通或路线规划,甚至用于人类语言及其语法。所有这些应用程序都有一个共同的挑战,即使用图的边遍历图并确保访问图的所有节点。有两种常见的已建立的方法来执行此遍历,如下所述。

Graphs are very useful data structures in solving many important mathematical challenges. For example computer network topology or analysing molecular structures of chemical compounds. They are also used in city traffic or route planning and even in human languages and their grammar. All these applications have a common challenge of traversing the graph using their edges and ensuring that all nodes of the graphs are visited. There are two common established methods to do this traversal which is described below.

Depth First Traversal

也称为深度优先搜索 (DFS),此算法以深度向运动遍历图,并使用栈来记住在任何迭代中发生死锁时获取下一个顶点以开始搜索。我们使用集合数据类型为 python 中的图实现 DFS,因为它们提供了跟踪已访问和未访问节点所需的功能。

Also called depth first search (DFS),this algorithm traverses a graph in a depth ward motion and uses a stack to remember to get the next vertex to start a search, when a dead end occurs in any iteration. We implement DFS for a graph in python using the set data types as they provide the required functionalities to keep track of visited and unvisited nodes.

Example

class graph:
   def __init__(self,gdict=None):
      if gdict is None:
         gdict = {}
      self.gdict = gdict
# Check for the visisted and unvisited nodes
def dfs(graph, start, visited = None):
   if visited is None:
      visited = set()
   visited.add(start)
   print(start)
   for next in graph[start] - visited:
      dfs(graph, next, visited)
   return visited

gdict = {
   "a" : set(["b","c"]),
   "b" : set(["a", "d"]),
   "c" : set(["a", "d"]),
   "d" : set(["e"]),
   "e" : set(["a"])
}
dfs(gdict, 'a')

Output

执行上述代码后,将生成以下结果 −

When the above code is executed, it produces the following result −

a
b
d
e
c

Breadth First Traversal

也称为广度优先搜索 (BFS),此算法以广度向运动遍历图,并使用队列来记住在任何迭代中发生死锁时获取下一个顶点以开始搜索。请访问我们网站上的此链接以了解图的 BFS 步骤的详细信息。

Also called breadth first search (BFS),this algorithm traverses a graph breadth ward motion and uses a queue to remember to get the next vertex to start a search, when a dead end occurs in any iteration. Please visit this link in our website to understand the details of BFS steps for a graph.

我们在 Python 中使用前面讨论过的队列数据结构来实现图的 BFS。当我们持续访问相邻未访问的节点并将它们添加到队列中时。然后我们仅对没有未访问节点的节点开始出队。当没有相邻节点要访问时,我们停止程序。

We implement BFS for a graph in python using queue data structure discussed earlier. When we keep visiting the adjacent unvisited nodes and keep adding it to the queue. Then we start dequeue only the node which is left with no unvisited nodes. We stop the program when there is no next adjacent node to be visited.

Example

import collections
class graph:
   def __init__(self,gdict=None):
      if gdict is None:
         gdict = {}
      self.gdict = gdict
def bfs(graph, startnode):
# Track the visited and unvisited nodes using queue
   seen, queue = set([startnode]), collections.deque([startnode])
   while queue:
      vertex = queue.popleft()
      marked(vertex)
      for node in graph[vertex]:
         if node not in seen:
            seen.add(node)
            queue.append(node)

def marked(n):
   print(n)

# The graph dictionary
gdict = {
   "a" : set(["b","c"]),
   "b" : set(["a", "d"]),
   "c" : set(["a", "d"]),
   "d" : set(["e"]),
   "e" : set(["a"])
}
bfs(gdict, "a")

Output

执行上述代码后,将生成以下结果 −

When the above code is executed, it produces the following result −

a
c
b
d
e

Python - Algorithm Analysis

算法的效率可以在两个不同的阶段进行分析,在实现之前和实现之后。它们如下所示 −

Efficiency of an algorithm can be analyzed at two different stages, before implementation and after implementation. They are the following −

  1. A Priori Analysis − This is a theoretical analysis of an algorithm. Efficiency of an algorithm is measured by assuming that all other factors, for example, processor speed, are constant and have no effect on the implementation.

  2. A Posterior Analysis − This is an empirical analysis of an algorithm. The selected algorithm is implemented using programming language. This is then executed on target computer machine. In this analysis, actual statistics like running time and space required, are collected.

Algorithm Complexity

假设 X 是一个算法, n 是输入数据的大小,算法 X 使用的时间和空间是决定 X 效率的两个主要因素。

Suppose X is an algorithm and n is the size of input data, the time and space used by the algorithm X are the two main factors, which decide the efficiency of X.

  1. Time Factor − Time is measured by counting the number of key operations such as comparisons in the sorting algorithm.

  2. Space Factor − Space is measured by counting the maximum memory space required by the algorithm.

算法 f(n) 的复杂度根据输入数据的规模 n 给出了算法的运行时间和/或存储空间要求。

The complexity of an algorithm f(n) gives the running time and/or the storage space required by the algorithm in terms of n as the size of input data.

Space Complexity

算法的空间复杂度表示算法在其生命周期中所需的内存空间量。算法所需的存储空间等于以下两个部分的和 −

Space complexity of an algorithm represents the amount of memory space required by the algorithm in its life cycle. The space required by an algorithm is equal to the sum of the following two components −

  1. A fixed part that is a space required to store certain data and variables, that are independent of the size of the problem. For example, simple variables and constants used, program size, etc.

  2. A variable part is a space required by variables, whose size depends on the size of the problem. For example, dynamic memory allocation, recursion stack space, etc.

任何算法 P 的空间复杂度 S(P) 为 S(P) = C + SP(I),其中 C 是固定部分,S(I) 是算法的可变部分,它取决于实例特征 I。以下是一个尝试解释该概念的简单示例 −

Space complexity S(P) of any algorithm P is S(P) = C + SP(I), where C is the fixed part and S(I) is the variable part of the algorithm, which depends on instance characteristic I. Following is a simple example that tries to explain the concept −

Algorithm: SUM(A, B)

Algorithm: SUM(A, B)

步骤 1 − 开始

Step 1 − START

步骤 2 − C ← A + B + 10

Step 2 − C ← A + B + 10

步骤 3 − 停止

Step 3 − Stop

这里我们有三个变量 A,B 和 C 以及一个常量。因此 S(P) = 1 + 3。现在,空间取决于给定变量和常量类型的数据类型,并将相应地进行乘法。

Here we have three variables A, B, and C and one constant. Hence S(P) = 1 + 3. Now, space depends on data types of given variables and constant types and it will be multiplied accordingly.

Time Complexity

算法的时间复杂度表示算法运行到完成所需的时间量。时间要求可以定义为一个数值函数 T(n),其中 T(n) 可以测量为步骤数,前提是每个步骤消耗恒定时间。

Time complexity of an algorithm represents the amount of time required by the algorithm to run to completion. Time requirements can be defined as a numerical function T(n), where T(n) can be measured as the number of steps, provided each step consumes constant time.

例如,添加两个 n 位整数需要 n 步。因此,总计算时间为 T(n) = c ∗ n,其中 c 是添加两位数所需的时间。在这里,我们观察到随着输入大小的增加,T(n) 会线性增长。

For example, addition of two n-bit integers takes n steps. Consequently, the total computational time is T(n) = c ∗ n, where c is the time taken for the addition of two bits. Here, we observe that T(n) grows linearly as the input size increases.

Python - Algorithm Types

必须分析算法的效率和准确性,以对它们进行比较并针对特定方案选择特定算法。进行此分析的过程称为渐近分析。它指的是用数学计算单位计算任何运算的运行时间。

The efficiency and accuracy of algorithms have to be analysed to compare them and choose a specific algorithm for certain scenarios. The process of making this analysis is called Asymptotic analysis. It refers to computing the running time of any operation in mathematical units of computation.

例如,一个运算的运行时间计算为 f(n),另一个运算的运行时间可能计算为 g(n2)。这意味着第一个运算的运行时间将随着 n 的增加而线性增加,而第二个运算的运行时间在 n 增加时将呈指数增加。类似地,如果 n 非常小,则这两个运算的运行时间将几乎相同。

For example, the running time of one operation is computed as f(n) and may be for another operation it is computed as g(n2). This means the first operation running time will increase linearly with the increase in n and the running time of the second operation will increase exponentially when n increases. Similarly, the running time of both operations will be nearly the same if n is significantly small.

通常,算法所需的时间分为以下三种类型−

Usually, the time required by an algorithm falls under three types −

  1. Best Case − Minimum time required for program execution.

  2. Average Case − Average time required for program execution.

  3. Worst Case − Maximum time required for program execution.

Asymptotic Notations

常用的渐进符号来计算算法的运行时间复杂度。

The commonly used asymptotic notations to calculate the running time complexity of an algorithm.

  1. Ο Notation

  2. Ω Notation

  3. θ Notation

Big Oh Notation, Ο

符号 Ο(n) 是表示算法运行时间上限的正式方法。它测量最坏情况时间复杂度或算法可能花费的最长时间来完成。

The notation Ο(n) is the formal way to express the upper bound of an algorithm’s running time. It measures the worst case time complexity or the longest amount of time an algorithm can possibly take to complete.

big o notation

例如,对于函数 f(n)

For example, for a function f(n)

Ο(f(n)) = { g(n) : there exists c > 0 and n0 such that f(n) ≤ c.g(n) for all n > n0. }

Omega Notation, Ω

符号 Ω(n) 是表示算法运行时间下限的正式方法。它测量最佳情况时间复杂度或算法可能花费的最短时间来完成。

The notation Ω(n) is the formal way to express the lower bound of an algorithm’s running time. It measures the best case time complexity or the best amount of time an algorithm can possibly take to complete.

omega notation

例如,对于函数 f(n)

For example, for a function f(n)

Ω(f(n)) ≥ { g(n) : there exists c > 0 and n0 such that g(n) ≤ c.f(n) for all n > n0. }

Theta Notation, θ

符号 θ(n) 是表示算法运行时间上下限的正式方法。它表示如下−

The notation θ(n) is the formal way to express both the lower bound and the upper bound of an algorithm’s running time. It is represented as follows −

theta notation
θ(f(n)) = { g(n) if and only if g(n) =  Ο(f(n)) and g(n) = Ω(f(n)) for all n > n0. }

Common Asymptotic Notations

下面列出了一些常见的渐进符号−

A list of some common asymptotic notations is mentioned below −

constant

Ο(1)

logarithmic

Ο(log n)

linear

Ο(n)

n log

Ο(n log n)

quadratic

Ο(n2)

cubic

Ο(n3)

polynomial

nΟ(1)

exponential

2Ο(n)

Python - Algorithm Classes

算法是明确的步骤,应该通过处理零个或多个输入向我们提供明确定义的输出。这导致了设计和编写算法的多种方法。已经观察到,大多数算法可以归类为以下类别。

Algorithms are unambiguous steps which should give us a well-defined output by processing zero or more inputs. This leads to many approaches in designing and writing the algorithms. It has been observed that most of the algorithms can be classified into the following categories.

Greedy Algorithms

贪婪算法尝试找到局部最优解,这最终可能会导致全局最优解。但是,贪婪算法通常不提供全局最优解。

Greedy algorithms try to find a localized optimum solution, which may eventually lead to globally optimized solutions. However, generally greedy algorithms do not provide globally optimized solutions.

因此,贪婪算法在此时刻寻找一个简单的解决方案,而无需考虑它如何影响未来的步骤。它类似于人类在不了解所提供输入的完整细节的情况下解决问题的方式。

So greedy algorithms look for a easy solution at that point in time without considering how it impacts the future steps. It is similar to how humans solve problems without going through the complete details of the inputs provided.

大多数联网算法都采用贪婪方法。这里列出一些此类算法−

Most networking algorithms use the greedy approach. Here is a list of few of them −

  1. Travelling Salesman Problem

  2. Prim’s Minimal Spanning Tree Algorithm

  3. Kruskal’s Minimal Spanning Tree Algorithm

  4. Dijkstra’s Minimal Spanning Tree Algorithm

Divide and Conquer

此类算法涉及将给定问题分成较小的子问题,然后独立解决每个子问题。当问题无法进一步子划分时,我们开始合并每个子问题的解,以得出更大问题的解。

This class of algorithms involve dividing the given problem into smaller sub-problems and then solving each of the sub-problem independently. When the problem can not be further sub divided, we start merging the solution to each of the sub-problem to arrive at the solution for the bigger problem.

分而治之算法的重要示例有 −

The important examples of divide and conquer algorithms are −

  1. Merge Sort

  2. Quick Sort

  3. Kruskal’s Minimal Spanning Tree Algorithm

  4. Binary Search

Dynamic Programming

动态规划涉及将较大的问题划分为较小的子问题,但与分而治之不同,它不涉及独立解决每个子问题。相反,它会记住较小子问题的结果,并将其用于相似或重叠的子问题。

Dynamic programming involves dividing the bigger problem into smaller ones but unlike divide and conquer it does not involve solving each sub-problem independently. Rather the results of smaller sub-problems are remembered and used for similar or overlapping sub-problems.

大多数情况下,这些算法用于优化。在解决手头的子问题之前,动态算法会尝试检查以前解决的子问题的结果。动态算法的动机是对问题进行整体优化,而不是局部优化。

Mostly, these algorithms are used for optimization. Before solving the in-hand sub-problem, dynamic algorithm will try to examine the results of the previously solved sub-problems.Dynamic algorithms are motivated for an overall optimization of the problem and not the local optimization.

动态规划算法的重要示例有 −

The important examples of Dynamic programming algorithms are −

  1. Fibonacci number series

  2. Knapsack problem

  3. Tower of Hanoi

Python - Amortized Analysis

摊销分析涉及估算程序中一系列操作的运行时间,而不考虑输入值中数据分布的跨度。一个简单的例子是在排序列表中查找值比在未排序列表中查找值更快。

Amortized analysis involves estimating the run time for the sequence of operations in a program without taking into consideration the span of the data distribution in the input values. A simple example is finding a value in a sorted list is quicker than in an unsorted list.

如果列表已经排序,那么数据如何分布并不重要。但当然列表的长度会产生影响,因为它决定了算法必须经历的步骤数才能得到最终结果。

If the list is already sorted, it does not matter how distributed the data is. But of course the length of the list has an impact as it decides the number of steps the algorithm has to go through to get the final result.

因此,我们看到,如果获取排序列表的单个步骤的初始成本很高,则查找元素的后续步骤的成本会大大降低。因此,摊销分析可帮助我们找到一系列操作的最坏情况运行时间的界限。摊销分析有三种方法。

So we see that if the initial cost of a single step of obtaining a sorted list is high, then the cost of subsequent steps of finding an element becomes considerably low. So Amortized analysis helps us find a bound on the worst-case running time for a sequence of operations. There are three approaches to amortized analysis.

  1. Accounting Method − This involves assigning a cost to each operation performed. If the actual operation finishes quicker than the assigned time then some positive credit is accumulated in the analysis.

  2. Potential Method − In this method the saved credit is utilized for future operations as mathematical function of the state of the data structure. The evaluation of the mathematical function and the amortized cost should be equal. So when the actual cost is greater than amortized cost there is a decrease in potential and it is used utilized for future operations which are expensive.

  3. *Aggregate analysis * − In this method we estimate the upper bound on the total cost of n steps. The amortized cost is a simple division of total cost and the number of steps (n)..

Python - Algorithm Justifications

为了对算法的效率做出宣称,我们需要一些数学工具作为证明。这些工具帮助我们对算法的性能和准确性提供了数学上令人满意的解释。以下是可用于证明一种算法优于另一种算法的一些数学工具列表。

In order to make claims about an Algorithm being efficient we need some mathematical tools as proof. These tools help us on providing a mathematically satisfying explanation on the performance and accuracy of the algorithms. Below is a list of some of those mathematical tools which can be used for justifying one algorithm over another.

  1. Direct Proof − It is direct verification of the statement by using the direct calculations. For example sum of two even numbers is always an even number. In this case just add the two numbers you are investigating and verify the result as even.

  2. Proof by induction − Here we start with a specific instance of a truth and then generalize it to all possible values which are part of the truth. The approach is to take a case of verified truth, then prove it is also true for the next case for the same given condition. For example all positive numbers of the form 2n-1 are odd. We prove it for a certain value of n, then prove it for the next value of n. This establishes the statement as generally true by proof of induction.

  3. Proof by contraposition − This proof is based on the condition If Not A implies Not B then A implies B. A simple example is if square of n is even then n must be even. Because if square on n is not even then n is not even.

  4. Proof by exhaustion − This is similar to direct proof but it is established by visiting each case separately and proving each of them. An example of such proof is the four color theorem.