数值方法入门/Python 编程
目标
- 熟悉 Python 编程语言和命令行界面
- 使用正确的控制结构
- 用正确的语法编写简单的 Python 程序
- 导入和使用库
资源
- 计算科学与工程 Python 入门 (初学者指南)
- 谷歌的 Python 开发者课程
- Python 初学者教程
- 官方 Python 教程
- 官方 Python 初学者教程
- Python 入门
- IPython
Python 是一种脚本语言。您可以使用交互式 Python 控制台来编写和执行代码。登录 Unix/Linux 系统后,您可以键入 "python"(带引号)启动控制台,然后按 ^D(ctrl+D)退出控制台。这种交互性使其非常适合探索性发现 - 通过探索和实验找到解决方案。
Python 控制台执行一个读取-求值-打印循环 (REPL),这意味着它会提示您输入表达式/命令,一旦您按下回车键,它就会读取您的表达式,对其进行求值,打印表达式的值,并提示您输入下一个表达式。这使得测试 Python 语句变得非常容易。您可以将其用作计算器
>>>1+2
3
>>>2**3
8
>>> # this is a comment
...
>>> 2**0.5
1.4142135623730951
许多有用的函数已在库中实现。要使用这些函数,您需要导入它们,以便识别它们的名称。dir() 函数打印模块中可用对象的目录(函数)
>>>import math
>>>dir(math)
['__doc__', '__name__', '__package__', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atan2', 'atanh', 'ceil',
'copysign', 'cos', 'cosh', 'degrees', 'e', 'erf', 'erfc', 'exp', 'expm1', 'fabs', 'factorial', 'floor', 'fmod',
'frexp', 'fsum', 'gamma', 'hypot', 'isinf', 'isnan', 'ldexp', 'lgamma', 'log', 'log10', 'log1p', 'modf',
'pi', 'pow', 'radians', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'trunc']
>>> help(math.exp)
Help on built-in function exp in module math:
exp(...)
exp(x)
Return e raised to the power of x.
>>> # this is similar to 2 ** 0.5
>>> math.sqrt(2)
1.4142135623730951
help() 函数可用于查找库中对象的含义和用法,如前面的代码示例所示。请注意,您需要按字母 Q 退出帮助会话以返回到 Python 控制台。
Python 不是强类型语言,这意味着您不需要为变量声明特定的数据类型。但是与变量关联的数据项具有类型,这些类型是隐式的 - 从表达式或对数据项的操作派生。因此,变量的数据类型可能会随着时间的推移而改变。type() 函数将告诉您存储在变量中的数据类型。
>>> type(a)
<type 'int'>
>>> type(1)
<type 'int'>
>>> a = 1.0
>>> type(a)
<type 'float'>
>>> a = "one"
>>> type(a)
<type 'str'>
>>> a = False
>>> print a False
>>> type(a)
<type ’bool’>
>>> a = 1 + 2j
>>> type(a)
<type 'complex'>
>>> a = [1, 2, 3]
>>> type(a)
<type 'list'>
有一些函数可以在数据类型之间进行转换,例如 int()、float()、str() 和 list()。
>>> a = int("123")
>>> a
123
>>> type(a)
<type 'int'>
>>> a = float("123.4")
>>> a
123.4
>>> type(a)
<type 'float'>
>>> a = str(123.4)
>>> a
'123.4'
>>> type(a)
<type 'str'>
>>> a = list("one two three")
>>> a
['o', 'n', 'e', ' ', 't', 'w', 'o', ' ', 't', 'h', 'r', 'e', 'e']
>>> type(a)
<type 'list'>
数据类型会根据需要自动提升。
>>> import sys
>>> sys.maxint
9223372036854775807
>>> type(sys.maxint)
<type 'int'>
>>> type(sys.maxint+1)
<type 'long'>
在 Python 中,字符串、列表和元组是序列。它们可以像索引和切片一样被索引和切片。Python 中的列表可以包含不同类型的数据项。
>>> range(10)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> for i in range(10):
... print i ** 2
...
0
1
4
9
16
25
36
49
64
81
除了直接在控制台中编写和运行 Python 代码之外,您还可以将命令/语句保存在文件中,并使用 Python 解释器运行整个文件作为脚本。例如,在 shell 命令行中,您可以键入以下内容来运行名为 hello.py 的程序/脚本
python hello.py
缩进在 Python 中很重要,因为它用于定义作用域,从而消除了对大括号 {} 的使用。请确保同一级别的代码缩进量相同,用制表符或空格字符表示。
您可以使用类似于 C 中的 printf 函数的格式字符串来打印数字。
>>>a = 0.1
>>> a
0.1
>>>print "%20.19f" % a
0.1000000000000000056
此示例显示了浮点数表示的限制。1/10 无法精确表示,因为它不是 2 的幂。即使控制台将 a 打印为 0.1,但底层表示也几乎是 0.1。
>>> import math
>>> a = math.sqrt(2)
>>> a
1.4142135623730951
>>> a ** 2
2.0000000000000004
以下示例将无限循环,直到结果溢出寄存器,因为 x 永远不会完全变为 1.0,因为 0.1 的表示是一个近似值(存在误差)。
>>> x = 0.0
>>> while not x == 1.0:
... x = x + 0.1
... print("x=%19.17g" % (x))
...
x=0.10000000000000001
x=0.20000000000000001
x=0.30000000000000004
x=0.40000000000000002
x= 0.5
x=0.59999999999999998
x=0.69999999999999996
教训的寓意是:不要比较浮点数是否严格相等。或者,我们可以计算两个数字之间的距离,并在距离足够短时停止(小于阈值)。
>>> x = 0.0
>>> while abs(x - 1.0) > 1e-8:
... x = x + 0.1
... print("x=%19.17g" % (x))
...
x=0.10000000000000001
x=0.20000000000000001
x=0.30000000000000004
x=0.40000000000000002
x= 0.5
x=0.59999999999999998
x=0.69999999999999996
x=0.79999999999999993
x=0.89999999999999991
x=0.99999999999999989
如果我们知道要执行多少次迭代,我们可以使用如下所示的 for 循环。请注意,range(1, 11) => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]。
>>> for i in range(1, 11):
... x = i * 0.1
... print("x=%19.17g" % (x))
...
x=0.10000000000000001
x=0.20000000000000001
x=0.30000000000000004
x=0.40000000000000002
x= 0.5
x=0.60000000000000009
x=0.70000000000000007
x=0.80000000000000004
x=0.90000000000000002
x= 1
以下代码片段计算了什么?循环会结束吗?为什么?
>>> eps = 1.0
>>> while 1.0 + eps > 1.0:
... eps = eps / 2.0
...
>>> print eps
1.11022302463e-16
eps 的值将始终是 2 的幂,因此不会有任何舍入误差。但是,随着 while 循环的继续,eps 会越来越小。最终 eps 会变得非常小,以至于与 1.0 相比几乎为零,这意味着将其添加到 1.0 将导致 1.0。回想一下,机器精度是在添加到 1.0 时会导致不同于 1.0 的值的最小值。如果一个数字小于机器精度,则将其添加到 1.0 时不会产生任何影响。sys.float_info
告诉我们机器精度为 2.220446049250313e-16,略小于 2x1.11022302463e-16=2.22044604926e-16。这就是为什么当循环结束时 eps 等于 1.11022302463e-16 的原因。
Python 的 SymPy 库允许我们以符号方式(作为符号)操作变量。以下代码片段演示了 SymPy 的一些基本功能。
>>> from sympy import Symbol
>>> x = Symbol('x');
>>> x+2*x+3*x
6*x
>>> y=x+2*x+3*x
>>> y
6*x
>>> y.subs(x, 2)
12
>>> from sympy import diff
>>> diff(y, x)
6
>>> from sympy import sin, cos
>>> diff(sin(x), x)
cos(x)
>>> diff(cos(x), x)
-sin(x)
>>> y = 4 - 1/x
>>> y.diff()
x**(-2)
>>> y.diff().subs(x, 0.5)
4.00000000000000
>>> from sympy import series
>>> sin(x).series(x, 0)
x - x**3/6 + x**5/120 + O(x**6)
>>> sin(x).series(x, 0, 10)
x - x**3/6 + x**5/120 - x**7/5040 + x**9/362880 + O(x**10)
来源
Numpy 中的数组是相同类型元素的多维表格。这些元素由正整数元组索引。Numpy 数组的类名称是 ndarray,也称为数组。每个数组对象都有许多属性
- mdim:维度数
- shape:一个整数元组,指示数组在每个维度上的大小。具有 m 行和 n 列的矩阵将以 (m, n) 作为其形状。
- size:数组中元素的总数。
- dtype:数组中元素的类型。
您可以在 Ubuntu 上安装 numpy 和 scipy,如下所示
sudo apt-get install python-numpy python-scipy python-matplotlib python-sympy
可以使用不同的语法引用数组中的元素,如以下示例所示。
>>> from numpy import *
>>> a = arange(15).reshape(3, 5)
>>> a
array([[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14]])
>>> type(a)
<type 'numpy.ndarray'>
>>> a.shape
(3, 5)
>>> (rows, cols) = a.shape
>>> rows
3
>>> cols
5
>>> a.ndim
2
>>> a.size
15
>>> a[2, 3]
13
>>> a[2][3]
13
>>> a[-1]
array([10, 11, 12, 13, 14])
>>> a[-2]
array([5, 6, 7, 8, 9])
>>> a[-2:]
array([[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14]])
>>> a[2:]
array([[10, 11, 12, 13, 14]])
>>> a[:-3]
array([], shape=(0, 5), dtype=int64)
>>> a[:]
array([[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14]])
>>> a[1, ...]
array([5, 6, 7, 8, 9])
>>> a[:, 0]
array([ 0, 5, 10])
可以使用 array 函数从常规 Python 列表或元组创建 Numpy 数组。数组元素的类型取决于序列中元素的类型。
>>> a = array([[1, 2], [2, 3]])
>>> a
array([[1, 2],
[2, 3]])
>>> a = array(((4, 5), (6, 7)))
>>> a
array([[4, 5],
[6, 7]])
>>> a.dtype
dtype('int64')
>>>>>> b = array([(1.2, 1.3), (1.4, 1.5)])
>>> b
array([[ 1.2, 1.3],
[ 1.4, 1.5]])
>>> b.dtype
dtype('float64')
NumPy 包含创建带有默认值的数组的函数。eye() 函数创建单位矩阵,identity() 函数执行类似的功能。copy 函数克隆数组对象,包括它包含的数据。
>>> zeros((2, 3))
array([[ 0., 0., 0.],
[ 0., 0., 0.]])
>>> ones((3, 4))
array([[ 1., 1., 1., 1.],
[ 1., 1., 1., 1.],
[ 1., 1., 1., 1.]])
>>> empty((2, 3))
array([[ 2.68156159e+154, 2.68156159e+154, 2.68156242e+154],
[ 2.68156159e+154, 2.68156159e+154, 2.68156159e+154]])
>>> eye(3, 3)
array([[ 1., 0., 0.],
[ 0., 1., 0.],
[ 0., 0., 1.]])
>>> identity(3, float)
array([[ 1., 0., 0.],
[ 0., 1., 0.],
[ 0., 0., 1.]])
NumPy 数组上的算术运算为逐元素运算。乘积 * 运算符执行逐元素乘法。dot 函数执行矩阵乘法。
>>> a
array([[1, 2],
[3, 4]])
>>> b = a.copy()
>>> b
array([[1, 2],
[3, 4]])
>>> a*b
array([[ 1, 4],
[ 9, 16]])
>>> dot(a, b)
array([[ 7, 10],
[15, 22]])
NumPy 还包含许多基本的线性代数函数。
>>> from numpy.linalg import *
>>> a = array([[1.0, 2.0], [3.0, 4.0]])
>>> a
array([[ 1., 2.],
[ 3., 4.]])
>>> a.transpose()
array([[ 1., 3.],
[ 2., 4.]])
>>> inv(a)
array([[-2. , 1. ],
[ 1.5, -0.5]])
>>> y = array([[5.], [7.]])
>>> solve(a, y)
array([[-3.],
[ 4.]])
IPython Notebook 是一种交互式环境,允许对您的 Python 命令进行编码、执行和记录。
资源