在计算机科学中,数据结构是一门进阶性课程,概念抽象,难度较大。Python语言的语法简单,交互性强。用Python来讲解数据结构等主题,比C语言等实现起来更为容易,更为清晰。
而对于自学Python的朋友往往会遇到数据结构的问题,和所有的现代编程语言一样,Python也有大量的功能和构造。然而,Python是少数的几种基本程序要素相当简单的语言之一。本文将开始介绍使用Python编程的一些基础知识。
Python程序包含一个或多个模块(module)。模块只不过是Python代码的一个文件,其中可以包含语句、函数定义和类定义。简短的Python程序也称为脚本(script),可以包含在一个模块之中。而较长的或较为复杂的程序,通常包含一个主模块和一个或多个支持模块。主模块包含了程序执行的起点,支持模块则包含了函数和类的定义。
接下来,我们来看一个完整的Python程序,它是一个和用户玩猜数字的游戏的程序。计算机要求用户输入数值范围的最小值和最大值。计算机随后“思考”出在这个范围之内的一个随机数,并且重复地要求用户猜测这个数,直到用户猜对了。在用户每次进行猜测之后,计算机都会给出一个提示,并且会在这个过程的最后显示出总的猜测次数。这个程序包含了几种类型的Python语句,例如,输入语句、输出语句、赋值语句、循环和条件语句,我们将在本章的后面介绍它们。这个程序还包含了一个函数的定义。
如下是该程序的代码,代码位于文件numberguess.py之中:
"""Author: Ken Lambert
Plays a game of guess the number with the user.
"""import randomdef main():
"""Inputs the bounds of the range of numbers
and lets the user guess the computer’s number until
the guess is correct."""
smaller=int(input("Enter the smaller number: "))
larger=int(input("Enter the larger number: "))
myNumber=random.randint(smaller, larger)
count=0
while True:
count +=1
userNumber=int(input("Enter your guess: "))
if userNumber < myNumber:
print("Too small")
elif userNumber > myNumber:
print("Too large")
else:
print("You’ve got it in", count, "tries!")
breakif __name__=="__main__":
main()
如下是一个用户和该程序的交互记录:
Enter the smaller number: 1Enter the larger number: 32Enter your guess: 16Too smallEnter your guess: 24Too largeEnter your guess: 20You’ve got it in 3 tries!
你可以在一个终端窗口中输入一条命令,来运行整个Python程序。例如,运行本书中给出的大多数示例。要运行numberguess.py文件中包含的程序,在大多数的终端窗口中,只要输入如下的命令就可以了:
python3 numberguess.py
要创建或编辑Python模块,尝试使用Python的IDLE(Integrated DeveLopment Environment,集成开发环境)。要启动IDLE,在一个终端提示符后输入idle或idle3,或者单击其图标。也可以通过在某个Python源代码文件(以.py为扩展名的任何文件)上单击,或者通过在一个文件上点击鼠标右键并选择“Open or Edit with IDLE”,来启动IDLE。确保将你的系统设置为在加载这种类型的文件的时候会打开IDLE。
IDLE提供了一个shell窗口,可以交互式地运行Python表达式和语句。使用IDLE,可以在编辑器窗口和shell窗口之间来回切换,以开发和运行完整的程序。IDLE还能够格式化代码,并为代码提供颜色区分。
当你用IDLE打开已有的Python文件的时候,文件会出现在编辑器窗口中,并且shell会在一个单独的窗口弹出。要运行一个程序,将光标移动到编辑器窗口中,并且按下F5键。Python会在编辑器窗口中编译代码,并且在shell窗口中运行它。
当运行包含几个Python模块的一个程序的时候,针对每个模块(除了主模块之外)编译后的代码,会被保存到一个二进制代码文件中(以.pyc为扩展名的一个文件)。Python加载这些文件,以便运行随后的程序(如果没有对相应的.py文件做出修改的话)。
如果一个Python程序挂起了或者没有正常结束的话,可以按下Ctrl+C键或关闭shell窗口来退出。
程序注释是Python编译器会忽略的文本,但是,作为文档,它对于程序的阅读者很有价值。Python中的单行注释以一个#符号开头,并且到当前行的末尾结束。它的颜色是红色的(尽管由于本书是黑白印刷的,你并看不出来这一点)。如下所示:
# This is an end-of-line comment.
一个多行注释是用3个单引号或3个双引号括起来的一个字符串。这样的注释也叫作文档字符串(docstring),表明它们可以记录程序中的主要结构。前面给出的猜数字程序就包含了两个文档字符串。第一个文档字符串在程序文件的顶部,充当了整个numberguess模块的注释。第二个文档字符串在主函数的头部之下,描述了这个函数做什么事情。尽管文档字符串看上去很简短,但是它们能在Python shell中为程序员提供帮助,因此扮演了一个重要的角色。
语言中的词法元素是用于构造语句一类的单词和符号。和所有的高级编程语言一样,Python的一些基本符号是关键字,例如if、while和def。还包括了其他的一些词法元素,例如标识符(名称)、字面值(数字、字符串和其他内建的数据结构)、运算符和分隔符(引号、逗号、圆括号、方括号和花括号)。
Python关键字和名称都是区分大小写的。因此,while是一个关键字,而While则是程序员定义的一个名称。Python关键字是以小写字母的方式拼写的,并且在IDLE窗口中以橙色表示。
所有的Python名称,其颜色都是黑色的,除非将其作为函数、类或方法名来引用,在这种情况下,它们显示为蓝色。名称可以以一个字母或一个下划线(‘_’)开头,后面跟着任意多个字母、下划线或者数字。
在本书中,模块、变量、函数和方法的名称,都是以小写字母的形式来拼写的。模块名只有一种例外,就是当一个模块名包含了一个或多个嵌入的名称的时候,嵌入的名称都是大写的。类名也遵从相同的命名惯例,但是,类名的首字母是大写的。当一个变量名是一个常量的时候,其所有的字母都是大写的,并且会有一个下划线用来隔开任何嵌入的名称。表1.1给出了这些命名惯例的示例。
表1.1 Python命名惯例的示例
名称类型
示例
变量
salary, hoursWorked, isAbsent
常量
ABSOLUTE_ZERO, INTEREST_RATE
函数或方法
printResults, cubeRoot, isEmpty
类
BankAccount, SortedSet
要使用能够描述其在程序中的角色的名称。通常,变量名应该是名词或形容词(如果它们表示布尔值的话,就是形容词),而函数和方法名应该是动词(如果它们表示动作)或者名词或形容词(如果它们表示返回的值)。
一种语言的语法元素是由词法元素组成的语句(表达式、语句和其他结构)的类型。和大多数的高级语言不同,Python使用空白(空格、制表符和换行)来标记多种类型的语句的语法。这意味着,在Python代码中,缩进和换行是很重要的。像IDLE这样的智能编辑器,能够帮助乐器正确地缩进。程序员不需要操心用分号隔开句子,或者用花括号来标记语句块。在本书所有的Python代码中,我使用4个空格宽度的缩进。
数字(整数或浮点数)的写法和在其他编程语言中的写法都是一样的。布尔值True和False都是关键字。一些数据结构,例如字符串、元组、列表和字典,也拥有字面值,稍后我们将会看到这一点。
可以用单引号、双引号,或者成对的三个双引号或三个单引号将字符串括起来。最后的这种表示方法,对于包含多行文本的字符串来说,是很有用的。字符值是单字符的字符串。\字符用于将非图形化的字符(例如,换行
和制表符 ,或者\字符本身)进行转义。下面的代码段及其输出,展示了各种可能性:
print("Using double quotes")print(’Using single quotes’)print("Mentioning the word ’Python’ by quoting it")print("Embedding a
line break with \
")print("""Embedding a
line break with triple quotes""")
输出:
Using double quotesUsing single quotesMentioning the word ’Python’ by quoting itEmbedding a
line break with
Embedding a
line break with triple quotes
算术表达式使用标准的运算符(+、–、和/)和中缀表示法。/运算符对于任何数字运算数,都会生成一个浮点数的结果,而//运算符则会产生一个整数的商。当+运算符用于集合(例如,字符串和列表)的时候,它表示连接。*运算符用于指数运算。
比较运算符(<、<=、>、>=、==和!=)用于数字和字符串。==运算符比较数据结构内部的内容(例如,两个列表)在结构上的相等性。is运算符比较对象实体的两个值。比较会返回True或False。
逻辑运算符and、or和not会将几个值(例如0、None、空字符串和空列表)作为False对待。相反,它们会将大多数其他的Python值当作True对待。
下标运算符[]和集合一起使用,稍后将会介绍它。
选择器运算符.用于引用一个模块、类或对象中的一个具名的项。
运算符都有标准的优先级(依次是选择器运算符、函数调用、下标运算符、算术运算符、比较运算符、逻辑运算符、赋值运算符)。括号通常用于将一个子表达式括起来,方便更早地运算它。**和=运算符是右结合性的,而其他的运算符是左结合性的。
函数调用的通常形式是函数名后面跟着用括号括起来的参数列表。例如:
min(5, 2) # Returns 2
Python包含了一些标准的函数,例如abs和round。很多其他的函数,可以通过导入模块的方式而变得可用,稍后你将会看到这一点。
标准输出函数print会将其参数显示到控制台。这个函数允许不同个数的参数。Python自动在每个参数上运行str函数,以获取其字符串表示,并且在输出之前用一个空格将每一个字符串隔开。默认情况下,输出结束的时候会使用一个换行。
标准输入函数input会等待用户通过键盘输入文本。当用户按下回车键的时候,该函数返回了包含所输入的字符的一个字符串。这个函数接受一个可选的字符串作为其参数,并且会不换行地打印出这个字符串,以提示用户进行输入。
可以将一些数据类型名称当作类型转换函数来使用。例如,当用户输入一个数字的时候,input函数返回数字组成的一个字符串,而不是一个数字值。程序必须先把这个字符串转换为int类型或float类型,然后才能够进行数字处理。下面的代码段输入了一个圆的半径,将这个字符串转换为float型,然后计算并输出了这个圆形的面积:
radius=float(input("Radius: "))print("The area is", 3.14 radius * 2)
和大多数其他的编程语言一样,Python允许算术表达式中的运算数具有不同的数值类型。在这种情况下,结果的类型和最为通用的运算数的类型相同。例如,int型和float型相加,将会得到float型的结果。
函数允许可选的参数,可选的参数在函数调用的时候是通过关键字来指定的。例如,print函数默认地会在其要显示的参数后面输出一个换行。为了阻止这种情况发生,可以给可选的参数end一个空字符串的值,如下所示:
print("The cursor will stay on this line, at the end", end="")
必需的参数是没有默认值的。可选的参数有默认值,并且当使用其关键字的时候,它们可以按照任意的顺序出现,只要都放在必需的参数之后就可以了。
例如,标准函数round期望一个必需的参数,这是一个舍入的值。还有一个可选的参数,表示精度的位数。当省略第2个参数的时候,该函数返回最近的整数值(int型)。当包含第2个参数的时候,该函数返回float型。
通常,调用函数的时候传递给它的参数的个数,至少要和它的必需参数的个数相同。
在调用标准函数和Python的库函数时,它们会检查其参数的类型。程序员定义的函数可以接受任意类型的参数,包括函数和类型自身。
一个Python变量是通过一条赋值语句来引入的。例如:
PI=3.1416
将PI的值设为3.1416。一条简单的赋值语句的语法是:
=
在同一条赋值语句中可以引入多个变量,如下所示:
minValue, maxValue=1, 100
要交换变量a和变量b的值,可以像下面这样编写代码:
a, b=b,a
赋值语句必须出现在单个的一行代码之中,除非这一行是在一个逗号、圆括号、花括号或方括号之后换行。当不具备这些选择的时候,在一条语句中换行的另一种方式是,用一个转义字符\来结束一行。通常将这个符号放在一个表达式中的运算符之前或之后。如下是一些显然不太符合实际情况的例子:
minValue=min(100,
200) product=max(100, 200) \ *30
当你在一个逗号或转义符号之后按下回车键的时候,IDLE会自动缩进下一行的代码。
在Python中,任何变量都可以指定任何类型的一个值。变量不会声明为某一个类型,这和很多其他语言中的情况不同,变量会被直接赋一个值。
因此,数据类型名称不会出现在Python程序中。然而,所有的值和对象都是有类型的。表达式中的运算数的类型会在运行时检查,因此,类型错误一定会进行检查;然而,在编写代码的时候,程序员不必关心数据类型。
import语句使得另一个模块中的标识符可以被一个程序所见到。这些标识符可能是对象名、函数名或类名。有几种方式可以表示一条import语句。最简单的方式是,导入一个模块名称,例如:
import math
这使得在math模块中定义的任何名称,在当前的模块中都可以通过math.形式的语法而变得可用。因此,math.sqrt(2)将会返回2的平方根。
另一种导入的形式是,只导入要使用的名称自身,这样一来,就可以不带有模块名作为前缀而直接使用该名称了:
from math import sqrtprint(sqrt(2))
可以通过列出几个单独的名称来导入它们:
from math import pi, sqrtprint(sqrt(2) * pi)
可以使用*运算符导入一个模块中所有的名称,但是,我们并不认为这是好的做法。
尽管Python的Web站点www.python.org拥有Python语言的完整文档,但是在Python shell中也可以快速获取和语言大部分组成部分相关的帮助信息。要访问这样的帮助信息,只需要在shell提示符中输入名为help()的函数,其中的是模块、数据类型、函数或方法的名称。例如,调用help(abs)和(math.sqrt)分别会显示abs和math.sqrt函数的文档。调用help(int)和help(math)将会分别显示int类型和math模块中的所有操作的文档。
注意,如果一个模块并非是在shell启动的时候Python将要加载的内建模块,程序员必须先导入模块,然后才能请求关于它的帮助信息。例如,shell中的如下会话,将会显示本章前面所介绍的numberguess程序的文档:
>>> import numberguess>>> help(numberguess)Help on module numberguess: NAME
numberguess
DESCRIPTION
Author: Ken Lambert
Plays a game of guess the number with the user. FUNCTIONS
main()
Inputs the bounds of the range of numbers,
andletstheuserguessthecomputer’snumberuntil
the guess is correct. FILE /Users/ken/Documents/CS2Python/Chapters/Chapter1/numberguess.py
Python包含了针对序列、条件式执行和迭代等情况的、常见的各种控制语句。语句的序列是一条接着一条编写的一组语句。一个序列中的每一条语句,都必须以相同的缩进开始。本节将会介绍条件式执行和迭代的控制语句。
本书摘自《数据结构(python描述)》
Python程序员学习路径之数据结构篇
在计算机科学中,数据结构是一门进阶性课程,概念抽象,难度较大。Python语言的语法简单,交互性强。用Python来讲解数据结构等主题,比C语言等实现起来更为容易,更为清晰。
本书第1章简单介绍了Python语言的基础知识和特性。第2章到第4章对抽象数据类型、数据结构、复杂度分析、数组和线性链表结构进行了详细介绍,第5章和第6章重点介绍了面向对象设计的相关知识、第5章包括接口和实现之间的重点差异、多态以及信息隐藏等内容,第6章主要讲解继承的相关知识,第7章到第9章以栈、队列和列表为代表,介绍了线性集合的相关知识。第10章介绍了各种树结构,第11章讲解了集和字典的相关内容,第12章介绍了图和图处理算法。每章最后,还给出了复习题和案例学习,帮助读者巩固和思考。