0 环境搭建
1.安装python
2.安装pycharm
3.安装anaconda
1 基本程序要素
Python 程序示例:猜数字
我们来看一个完整的 Python 程序,它是一个和用户玩猜数字的游戏的程序。
计算机要求用户输入数值范围的最小值和最大值。计算机随后“思考”出在这个范围之内的一个随机数,并且重复地要求用户猜测这个数,直到用户猜对了。在用户每次进行猜测之后,计算机都会给出一个提示,并且会在这个过程的最后显示出总的猜测次数。这个程序包含了几种类型的 Python 语句,例如,输入语句、输出语句、赋值语句、循环和条件语句,我们将在本章的后面介绍它们。这个程序还包含了一个函数的定义。
如下是该程序的代码,代码位于文件 numberguess.py 之中:
""" Author: Ken Lambert Plays a game of guess the number with the user. """ import random def 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!") break if __name__ == "__main__": main()
如下是一个用户和该程序的交互记录:
Enter the smaller number: 1 Enter the larger number: 32 Enter your guess: 16 Too small Enter your guess: 24 Too large Enter your guess: 20 You’ve got it in 3 tries!
你可以在一个终端窗口中输入一条命令,来运行整个 Python 程序。要运行 numberguess.py 文件中包含的程序,在大多数的终端窗口中,只要输入如下的命令就可以了:
python numberguess.py
程序注释
# This is an end-of-line comment.
语法元素
一种语言的语法元素是由词法元素组成的语句(表达式、语句和其他结构)的类型。和大多数的高级语言不同,Python 使用空白(空格、制表符和换行)来标记多种类型的语句的语法。这意味着,在 Python 代码中,缩进和换行是很重要的。我使用 4 个空格宽度的缩进。
字面值
数字(整数或浮点数)的写法和在其他编程语言中的写法都是一样的。布尔值 True 和False 都是关键字。一些数据结构,例如字符串、元组、列表和字典,也拥有字面值,稍后我们将会看到这一点
字符串字面值
可以用单引号、双引号,或者成对的三个双引号或三个单引号将字符串括起来。最后的这种表示方法,对于包含多行文本的字符串来说,是很有用的。字符值是单字符的字符串。\字符用于将非图形化的字符(例如,换行\n 和制表符\t,或者\字符本身)进行转义。下面的代码段及其输出,展示了各种可能性:
print("Using double quotes") print(’Using single quotes’) print("Mentioning the word ’Python’ by quoting it") print("Embedding a\nline break with \\n") print("""Embedding a line break with triple quotes""")
输出
Using double quotes Using single quotes Mentioning the word ’Python’ by quoting it Embedding a line break with \n 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 函数(输出)
标准输出函数 print 会将其参数显示到控制台。这个函数允许不同个数的参数。Python自动在每个参数上运行 str 函数,以获取其字符串表示,并且在输出之前用一个空格将每一个字符串隔开。默认情况下,输出结束的时候会使用一个换行。
input 函数(输入)
标准输入函数 input 会等待用户通过键盘输入文本。当用户按下回车键的时候,该函数返回了包含所输入的字符的一个字符串。这个函数接受一个可选的字符串作为其参数,并且会不换行地打印出这个字符串,以提示用户进行输入。
name = input("Enter the smaller number: ")
类型转换函数和混合模式运算
可以将一些数据类型名称当作类型转换函数来使用。例如,当用户输入一个数字的时候,input 函数返回数字组成的一个字符串,而不是一个数字值。程序必须先把这个字符串转换为 int 类型或 float 类型,然后才能够进行数字处理。下面的代码段输入了一个圆的半径,将这个字符串转换为 float 型,然后计算并输出了这个圆形的面积:
radius = float(input("Radius: ")) print("The area is", 3.14 * radius ** 2)
变量和赋值语句
一个 Python 变量是通过一条赋值语句来引入的。例如:
PI = 3.1416
将 PI 的值设为 3.1416。一条简单的赋值语句的语法是:
<identifier> = <expression>
在同一条赋值语句中可以引入多个变量,如下所示:
minValue, maxValue = 1, 100
要交换变量 a 和变量 b 的值,可以像下面这样编写代码:
a, b=b,a
Python 数据类型
在 Python 中,任何变量都可以指定任何类型的一个值。变量不会声明为某一个类型,这和很多其他语言中的情况不同,变量会被直接赋一个值。
因此,数据类型名称不会出现在 Python 程序中。然而,所有的值和对象都是有类型的。
表达式中的运算数的类型会在运行时检查,因此,类型错误一定会进行检查;然而,在编写代码的时候,程序员不必关心数据类型。
import 语句
import 语句使得另一个模块中的标识符可以被一个程序所见到。这些标识符可能是对象名、函数名或类名。有几种方式可以表示一条 import 语句。最简单的方式是,导入一个模块名称,例如:
import math
这使得在 math 模块中定义的任何名称,在当前的模块中都可以通过 math.<name>形式的语法而变得可用。因此,math.sqrt(2)将会返回 2 的平方根。
另一种导入的形式是,只导入要使用的名称自身,这样一来,就可以不带有模块名作为前缀而直接使用该名称了:
from math import sqrt print(sqrt(2))
可以通过列出几个单独的名称来导入它们:
from math import pi, sqrt print(sqrt(2) * pi)
可以使用*运算符导入一个模块中所有的名称,但是,我们并不认为这是好的做法。
2 控制语句
Python 包含了针对序列、条件式执行和迭代等情况的、常见的各种控制语句。语句的序列是一条接着一条编写的一组语句。一个序列中的每一条语句,都必须以相同的缩进开始。本节将会介绍条件式执行和迭代的控制语句。
条件语句
Python 的条件式语句的结构和其他语言中的条件式语句类似。关键词 if、elif 和else 是很重要的,冒号和缩进也同样重要。
单向的 if 语句的语法如下:
if <Boolean expression>: <sequence of statements>
正如前面提到的,布尔表达式(Boolean expression)可以是任何的 Python 值,其中的一些值被当作是 False,另一些值被当作是 True。如果布尔表达式为 True,就运行该语句序列,否则,什么也不会发生。语句序列(一条或多条语句)必须至少按照一个空格或制
表符(通常一个制表符是 4 个空格)来缩进或对齐。冒号是唯一的分隔符,如果序列中只有一条语句,它可以紧跟在同一行的冒号之后。
双向的 if 语句的语法如下:
if <Boolean expression>: <sequence of statements> else: <sequence of statements>
注意关键词 else 后面的冒号和缩进。这两个语句序列中,只有一个序列会运行。如果布尔表达式为 True,将会运行第 1 个序列;如果布尔表达式为 False,将会运行第 2个序列。
多向的 if 语句的语法如下:
if <Boolean expression>: <sequence of statements> elif <Boolean expression>: <sequence of statements> ... else: <sequence of statements>
多向的 if 语句也只会运行一个语句序列。多向的 if 语句包含了一个或多个可选的布尔表达式,其中的每一个布尔表达式都跟在关键字 elif 后面。你可以忽略掉最后一个 else:子句。下面的示例是比较两个数的大小的问题,并输出正确的答案:
if x > y: print("x is greater than y") elif x < y: print("x is less than y") else: print("x is equal to y")
使用 if name == "main"
前面讨论的 numberguess 程序包含了一个 main 函数的定义和如下的 if 语句:
if __name__ == "__main__": main()
这条 if 语句的作用是,允许程序员要么将模块当作一个独立的程序运行,要么从 shell或另一个模块中导入它。其工作方式如下。每个 Python 模块都包含一组内建的模块变量,当加载该模块的时候,Python 虚拟机会自动为这些变量赋值。
如果该模块是作为一个独立的程序加载(要么通过从一个终端提示符来运行它,要么从一个 IDLE 窗口加载它),该模块的name变量会设置为字符串"main"。否则,这个变量会设置为模块的名称,在这个例子中,也就是"numberguess"。不管怎么样,该变量的赋值都会在模块中的任何代码加载之前完成。因此,当执行到了模块末尾的 if 语句的时候,只有当模块是作为一个独立的程序启动的时候,才会调用模块的 main 函数。
循环语句
Python 的 while 循环语句的结构,类似于其他语言中的循环结构。其语法如下:
while <Boolean expression>: <sequence of statements>
下面的示例是计算从 1 到 10 的乘积并输出结果:
product = 1 value = 1 while value <= 10: product *= value value += 1 print(product)
注意,这里使用了扩展的赋值运算符*=。该行代码等价于如下的代码:
product = product * value
Python 包含了一个for 循环语句,以便更简洁地遍历值的一个序列。这条语句的语法如下:
for <variable> in <iterable object>: <sequence of statements>
当运行这个循环的时候,它将可迭代的对象(iterable object)中包含的每一个值都赋值给循环变量,并且在每一个赋值上下文中运行语句的序列。可迭代对象的示例是字符串和列表。下面的代码段使用了 Python 的 range 函数返回整数的一个可迭代的序列,从而计算
前面展示的乘积。
product = 1 for value in range(1, 11): product *= value print(product)
Python 程序员通常更喜欢使用一个 for 循环来遍历确定的范围的值或值的序列。当继续循环的条件是一个任意的布尔表达式的时候,程序员则使用 while 循环。
3字符串及其运算
和其他语言一样,Python 字符串也是一个复合对象,它包含了其他对象,也就是字符。然而,Python 中的每个字符,本身也是一个单个的字符的字符串,并且在字面上也采用了和字符串相似的方式来表示。Python 的字符串类型名为 str,其中包含了很多的运算,本节将会介绍其中的一些。
运算符
当使用比较运算符来比较字符串的时候,将会使用 ASCII 的顺序来比较两个字符串中的每一个位置的成对的字符。因此,"a"小于"b",而"A"小于"a"。
+运算符构建并返回一个新的字符串,它包含了两个运算数中的字符。
在下标运算符的最简单的形式中,它期待范围是从0到字符串的长度减去1的一个整数。该运算符返回在字符串中该位置的字符。因此:
"greater"[0] # Returns "g"
尽管字符串索引不能超过其长度减去 1,但是,负的索引是允许的。
当索引为负值的时候,Python 会将这个值和字符串的长度相加,以确定要返回的字符的位置。在这种情况下,所提供的负的索引值,不能够比字符串长度的负值还要小。
字符串是不可变的,也就是说,一旦创建了字符串,不能更改其内部的内容。因此,不能使用下标来替换字符串中一个给定位置的字符。
下标的一种变体,叫作切片(slice)运算符,可以用它来获取一个字符串的子字符串。
切片的语法如下:
<a string>[<lower>:<upper>]
如果给出了<lower>值的话,它的范围是从 0 到字符串的长度减去 1 的一个整数。如果给出了<upper>的话,它的范围是从 0 到字符串的长度的一个整数。
当这两个值都省略的时候,切片会返回整个字符串。当省略了第 1 个值的时候,切片会返回从字符串的第 1 个字符开始的一个子字符串。当省略了第 2 个值的时候,切片会返回到字符串的最后一个字符结束的一个子字符串。
否则,切片会返回从较低的索引值开始,到较高的索引值减去 1 结束的一个子字符串。
如下是使用切片运算的一些示例:
"greater"[:] # Returns "greater" "greater"[2:] # Returns "eater" "greater"[:2] # Returns "gr" "greater"[2:5] # Returns "eat"
对象和方法调用
除了标准的运算符和函数,Python 还包含了大量的可以操作对象的方法。方法和函数类似,方法也接受参数,执行一项任务并且返回一个值。然而,方法总是在相关联的对象之上调用。调用一个方法的语法如下所示:
<object>.<method name>(<list of arguments>)
如下是在字符串上调用方法的一些示例:
"greater".isupper() # Returns False "greater".upper() # Returns "GREATER" "greater".startswith("great") # Returns True
如果你试图运行一个对象所不识别的方法,Python 会抛出一个异常并且终止程序。想搞清楚在对象上能够识别一组什么样的方法,可以在 Python shell 中以该对象类型为参数来运行 Python 的 dir 函数。例如,dir(str)返回了字符串对象所识别的方法的一个列表。运行 help(str.upper)则会输出和 str.upper 方法用法相关的文档。
有些方法名,例如add和len,当 Python 看到一个对象和某种运算符或函数
一起使用的时候,就会运行这些方法。例如:
len("greater") # Is equivalent to "greater".__len__() "great" + "er" # Is equivalent to "great".__add__("er") "e" in "great" # Is equivalent to "great".__contains__("e")
4内建 Python 集合及其操作
列表
列表(list)是零个或多个 Python 对象的一个序列,这些对象通常称为项(item)。列表有一个字面的表示法,就是使用方括号将用逗号隔开的项括起来。下面是列表的一些示例:
[] # An empty list ["greater"] # A list of one string ["greater", "less"] # A list of two strings ["greater", "less", 10] # A list of two strings and an int ["greater", ["less", 10]] # A list with a nested list
和字符串一样,可以使用标准运算符对列表进行切片和连接。然而,在这种情况下,返回的结果也是列表。和字符串不同,列表是可变的,这意味着,可以替换、插入或删除列表中所包含的项。这一功能带来两个后果。首先,切片和连接运算符所返回的列表是新的列表,而不是最初列表的一部分。其次,列表类型包含了几个叫作修改器(mutator)的方法,它们的作用是修改一个列表的结构。可以在 Python shell 中输入 dir(list)来查看这些方法。
最常用的列表修改器方法是 append、insert、pop、remove 和 sort。如下是使用
这些方法的一些示例:
testList = [] # testList is [] testList.append(34) # testList is [34] testList.append(22) # testList is [34, 22] testList.sort() # testList is [22, 34] testList.pop() # Returns 22; testList is [34] testList.insert(0, 22) # testList is [22, 34] testList.insert(1, 55) # testList is [22, 55, 34] testList.pop(1) # Returns 55; testList is [22, 34] testList.remove(22) # testList is [34] testList.remove(55) # raises ValueError
字符串方法 split 和 join 分别从一个字符串中提取单词的一个列表并将单词列表组合到一起以形成一个字符串:
"Python is cool".split() #Returns[’Python’,’is’,’cool’] " ".join(["Python","is","cool"]) #Returns’Python is cool’
元组
元组(tuple)是项的一个不可变的序列。元组字面值用圆括号将各项括起来,并且元组必须至少包含两个项。元组实际上就像列表一样,只不过它没有修改器方法。要了解元组的可用方法,在 Python shell 中运行 dir(tuple)。
遍历序列
for 循环用来遍历一个序列(如字符串、列表或元组)中的项。例如,如下的代码段输出一个列表中的项:
testList = [67, 100, 22] for item in testList: print(item)
如下的代码是基于索引的遍历方法,显然上面的代码与其等价但是更简单一些:
testList = [67, 100, 22] for index in range(len(testList)): print(testList[index])
字典
字典(dictionary)包含零个或多个条目。每个条目(entry)都将一个唯一的键和一个值相关联。键通常是字符串或整数,而值是任何的 Python 对象。
字典字面值将键—值条目包含到一对花括号中,如下面的示例所示:
{} # An empty dictionary {"name":"Ken"} # One entry {"name":"Ken", "age":61} # Two entries {"hobbies":["reading", "running"]} # One entry, value is a list dic = {"name":"Ken", "age":61} for key,value in dic.items(): print(key, value)
我们使用下标运算符来访问一个给定键的值,给一个新键添加一个值,以及替换给定键的值。pop 方法删除条目,并且返回给定键的值。keys 方法返回键的一个可迭代的对象,而 values 方法返回值的一个可迭代的对象。for 循环可以遍历一个字典的键。
搜索一个值
程序员可以对值和集合使用 in 运算符,从而在字符串、列表、元组或字典中搜索一个值。这个运算符返回 True 或 False。字典搜索的目标值应该是一个潜在的键。当获知给定的值在一个序列(字符串、列表、元组)中时,index 方法将会返回第一次搜索到的这个值的位置。对于字典来说,get 和 pop 方法可以接受两个参数,一个键和一个默认值。搜索失败的话,将会返回该默认值;搜索成功的话,将会返回和该键相关联的值。
5 函数
函数定义
Python 函数的定义语法是:
def <function name>(<list of parameters>): <sequence of statements>
命名函数和参数的规则和惯例,与命名变量的是相同的。必需参数的列表可以为空,或者可以包含用逗号隔开的名称。和其他的编程语言不同,这里没有和参数名称或函数名自身相关联的数据类型。
如下是一个简单的函数,它计算并返回一个数字的平方:
def square(n): """Returns the square of n.""" result = n ** 2 return result
注意,在函数头的下方使用了带有 3 个引号的字符串。这是一个文档字符串(docstring)。这个字符串就像是函数中的注释一样,当用户在Python shell提示符窗口输入help(square)的时候,将会显示这个字符串。你所定义的每一个函数,都应该包含一个文档字符串,以说明这个函数做什么,并且给出与参数或返回值相关的任何信息。
函数可以引入新的变量,叫作临时变量(temporary variable)。在 square 函数中,n 是参数,result 是一个临时变量。函数的参数和临时变量,只有在函数调用的生命周期中存在,并且对其他的函数或外围程序是不可见的。因此,几个不同的函数可以使用相同的参数和变量名而不会导致冲突。
当一个函数并不包含 return 语句的时候,它在执行完最后一条语句的时候,会自动地返回一个 None 值。在模块中,可以按照任意的顺序来定义函数,只要在函数的定义被编译之前,不会真正地去执行函数就可以了。下面的示例展示了在模块开始处的一个非法的函数调用:
first() # Raises a NameError (function undefined yet) def first(): second() # Not an error, because not actually print("Calling first.") # called until after second is defined def second(): print("Calling second.") first() # Here is where the call should go
当 Python 运行第一行代码的时候,函数 first 还没有定义,因此,会抛出一个异常。如果在这行代码的开始处放置一个注释符号#,并且再次运行这段代码,程序将会运行并正常结束。在这个例子中,即便函数 second 似乎在定义它之前就调用了,但实际上直到调用函数 first 的时候,才真正地调用了 second,而这个时候,这两个函数都已经定义过了。
可以使用<parameter name> = <default value>的形式,带上为参数指定的默认值,从而将参数指定为可选的。在参数列表中,必需的参数(那些不带默认值的)必须要放在可选的参数之前。