Python 基础教程¶
高级语言的三种基本结构:
- 顺序结构:程序按照代码书写的先后顺序,从上到下逐行执行。这是最基础、最简单的程序结构。
- 选择结构:程序根据判断条件的真假,选择执行不同的分支路径。也称为分支结构或条件结构。
- 循环结构:程序在满足特定条件的情况下,反复执行某一段代码块,直到条件不再满足为止。也称为重复结构或迭代结构。
while 循环语句¶
# 斐波那契数列:
# 前两项之和即下一项的值
a, b = 0, 1
while a < 10:
print(a)
a, b = b, a+b
0 1 1 2 3 5 8
- 第一行中的多重赋值:变量 a 和 b 同时获得新值 0 和 1。最后一行又用了一次多重赋值,Python 会首先计算等号右边的所有表达式,将它们的值赋值给左边对应的变量。
- while 循环只要条件(这里是 a < 10)为真就会一直执行。Python 中任何非零整数都为真,零为假。
- 这个条件也可以是字符串或列表类型的值,任何序列长度非零就为真,空序列则为假。
- 示例中的判断是最简单的比较。比较操作符有:< (小于)、 > (大于)、 == (等于)、 <= (小于等于)、 >= (大于等于)及 != (不等于)。
- 循环体是缩进的:缩进是 Python 组织语句的方式,一般用4个空格代表一层,相同缩进的语句构成一个语句块。
if 条件语句¶
x = 42
if x < 0:
x = 0
print('把负数变成零')
elif x == 0:
print('零')
elif x == 1:
print('壹')
else:
print('更多')
更多
可有零个或多个 elif 部分,else 部分也是可选的。关键字 elif 是 else if 的缩写,用于避免过多的缩进。
x = 10
if x < 0:
x = 0
print('把负数变成零')
else:
if x == 0:
print('零')
else:
if x == 1:
print('壹')
else:
print('更多')
x
更多
10
for 循环语句¶
# 度量一些字符串:
words = ['cat', 'window', 'defenestrate']
for w in words:
print(w, len(w))
cat 3 window 6 defenestrate 12
Python 的 for 语句在列表或字符串等任意序列的元素上迭代,按它们在序列中出现的顺序进行。
range 函数¶
内置函数 range() 用于生成等差数列:
for i in range(5):
print(i)
0 1 2 3 4
生成的序列不包括给定的终止值;range(10) 生成 10 个值——长度为 10 的序列的所有合法索引。
range 可以不从 0 开始,且可以按给定的步长递增(即使是负数步长):
list(range(5, 10))
[5, 6, 7, 8, 9]
list(range(0, 10, 3))
[0, 3, 6, 9]
list(range(-10, -100, -30))
[-10, -40, -70]
要按索引迭代序列,可以组合使用 range() 和 len():
a = ['Mary', 'had', 'a', 'little', 'lamb']
for i in range(len(a)):
print(i, a[i])
0 Mary 1 had 2 a 3 little 4 lamb
这种情况一般使用 enumerate() 函数会更优雅:
for i, w in enumerate(a):
print(i, w)
0 Mary 1 had 2 a 3 little 4 lamb
如果直接打印一个 range 会发生意想不到的事情:
range(10)
range(0, 10)
range() 返回的对象在很多方面和列表的行为一样,但其实它和列表不一样。该对象只有在被迭代时才一个一个地返回所期望的列表项,并没有真正生成过一个含有全部项的列表,从而节省了空间。
这种对象称为可迭代对象 iterable,适合作为需要获取一系列值的函数或程序构件的参数。for 语句就是这样的程序构件;以可迭代对象作为参数的函数例如 sum():
sum(range(4)) # 0 + 1 + 2 + 3
6
定义函数¶
下列代码创建一个可以输出限定数值内的斐波那契数列函数:
def fib(n): # 打印小于 n 的斐波那契数列
a, b = 0, 1
while a < n:
print(a, end=' ')
a, b = b, a+b
print()
# 现在调用我们刚定义的函数:
fib(2000)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597
定义函数使用关键字 def,后跟函数名与括号内的形参列表。函数语句从下一行开始,并且必须缩进。
编写不直接输出斐波那契数列运算结果,而是返回运算结果列表的函数:
def fib2(n): # 返回斐波那契数组直到 n
result = []
a, b = 0, 1
while a < n:
result.append(a) # 见下
a, b = b, a+b
return result
f100 = fib2(100) # 调用它
f100 # 输出结果
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
return 语句返回函数的值。return 语句不带表达式参数时,返回 None。函数执行完毕退出也返回 None。
语句 result.append(a) 调用了列表对象 result 的方法。 方法是从属于对象的函数,其名称为 obj.methodname,其中 obj 是某个对象(可以是一个表达式),methodname 是由对象的类型定义的方法名称。 不同的类型定义了不同的方法。 不同的类型的方法可以使用相同的名称而不会产生歧义。在示例中显示的方法 append() 是由列表对象定义的;它会在列表的末尾添加一个新元素。
pass 语句¶
pass 语句不执行任何动作。语法上需要一个语句,但程序毋需执行任何动作时,可以使用该语句。例如:
while True:
pass # 无限等待键盘中断 (Ctrl+C)
--------------------------------------------------------------------------- KeyboardInterrupt Traceback (most recent call last) Cell In[15], line 2 1 while True: ----> 2 pass # 无限等待键盘中断 (Ctrl+C) KeyboardInterrupt:
pass 还可用作函数体的占位符:
def func():
pass # 记得实现这个!
使用抽象方法¶
抽象是从事物共性中提取关注的特征,忽略其他不关注的属性,从而形成一种可以代表一组相似事物的概念,是具体或特化的反面。
什么是“一”?¶
看一些可以代表“一”的例子。
from fractions import Fraction
import numpy as np
import matplotlib.pyplot as plt
ones = [1, 1.0, 'one', Fraction(1, 1), np.eye(2)]
ones
[1,
1.0,
'one',
Fraction(1, 1),
array([[1., 0.],
[0., 1.]])]
这个列表中的每一项都是“一”的一个具体的或特化的表示:
- 作为整数
- 作为浮点数
- 作为字符串
- 作为有理数
- 作为 2x2 单位矩阵
当然,这些只是"一"的几个例子。人们长期以来一直在用不同的语言、文字、艺术表达等方式来表示"一"。
计算机是如何根据输入的内容以不同方式看待"一"的?
computer_ones = [type(one) for one in ones]
computer_ones
[int, float, str, fractions.Fraction, numpy.ndarray]
计算机使用类型来区分不同的值。然而,不用类型的值在符合逻辑的情况下又可以支持相同的操作。
什么是"一"的集合?¶
现在想创建一个"一"的集合。下面是一种可以用不同的"一"来构建这个集合的方式。
element = ones[1]
array = np.full((3, 4), element)
array
array([[1., 1., 1., 1.],
[1., 1., 1., 1.],
[1., 1., 1., 1.]])
当使用不同的"一"时,这段代码几乎都是可以正常运行的。
这正是抽象的含义。换句话说,可以在一个不关心使用的是哪个具体"一"的层面上进行思考和操作。这表明抽象是特化的反面。
尝试使用抽象¶
现在想对一个"一"的集合执行某种操作,而不关心使用的是哪种"一"。
例如,想把一个矩阵复制一份,并修改其中某个位置的一个元素。
def insert(new, A, i, j):
B = A.copy()
B[i, j] = new
return B
one_number_array = np.full((3, 4), 1)
insert(5, one_number_array, 1, 2)
array([[1, 1, 1, 1],
[1, 1, 5, 1],
[1, 1, 1, 1]])
one_string_array = np.full((3, 4), 'one', dtype=np.dtypes.StringDType())
insert('five', one_string_array, 1, 2)
array([['one', 'one', 'one', 'one'],
['one', 'one', 'five', 'one'],
['one', 'one', 'one', 'one']], dtype=StringDType())
insert 函数只关心如何将一个对象插入数组,而对数组内部的内容一无所知,但它却能够用于两个完全不同的数组——任意类型的"一"的集合。
本讲小结¶
- Python 的基本语法
- 条件
if - 循环
while、for - 函数定义与调用
- 条件
- 抽象方法
- 计算机语言支持抽象,在编写程序时可以消除掉具体细节,做一些更通用的事情