基础数学运算
Pythora 星球的人常常会把 Python 当做计算器来用,尤其是需要计算很多数据的时候,它比计算器还方便。Python 不仅支持基本的数学运算,如加法、 减法、乘法和除法,还支持更复杂的数学操作,如指数运算、模运算、整数除法等。
整数 (Integers)
四则运算
Python 对于整数的运算与数学表达式基本一致,比如最简单的加减法运算:
print(3 + 2) # 输出 5
print(5 - 2) # 输出 3
Python 和大多数语言一样,使用星号 * 表示乘法,使用斜杠 / 表示除法。在 Python 2 中, 整数的 / 运算返回的依然还是整数结果,但在目前主要使用的 Python 3 中,整数的 / 运算结果可能是个浮点数。Python 3 使用双斜杠 // 表示整除运算;使用百分号 % 表示取模(余数)运算;使用双星号 ** 表示幂运算:
print(4 * 3) # 输出 12
print(8 / 3) # 输出 2.666...
print(8 // 3) # 输出 2
print(8 % 3) # 输出 2
print(2 ** 4) # 输出 16
+ 和 - 除了表示加法减法之外,还被用来表示正负数,比如 +2、-5 等,正负号运算级别要高于其它运算符。那么大家猜一下运行下面的程序会出现什么结果?
print(2*-5)
print(1+++2)
print(1+-+-+-+-+2)
进制
Python 中可以使用不同进制来表示一个整数。最常见的十进制(Decimal)整数是没有特殊的前缀的,比如 42。
二进制(Binary)整数使用 0b 或 0B 前缀来表示,比如 0b101010 表示十进制的 42。
八进制(Octal)整数使用 0o 或 0O 前缀来表示,比如 0o52 表示十进制的 42。
十六进制(Hexadecimal)整数使用 0x 前缀来表示,比如 0x2A 或 0x2a 表示十进制的 42。
使用 Python 的内置函数可以把一个整数转换成不同进制的字符串:
bin(x):将整数 x 转换为二进制字符串。 oct(x):将整数 x 转换为八进制字符串。 hex(x):将整数 x 转换为十六进制字符串。 int(string, base):将给定进制的字符串转换为十进制整数。
比如:
x = 42
print(bin(x)) # 输出 '0b101010'
print(oct(x)) # 输出 '0o52'
print(hex(x)) # 输出 '0x2a'
y = '0b101010'
print(int(y, 2)) # 输出 42
用函数 int() 可以把其它类型的数据转换成整数。
浮点数 (Floats)
四则运算
浮点数就是我们常说的小数,实数。它的计算与整数类似,但结果可能带有小数,比如:
print(3.0 + 2.5) # 输出 5.5
print(5.5 - 2.5) # 输出 3.0
print(4.0 * 3.0) # 输出 12.0
print(8.0 / 3.0) # 输出 2.666...
表示法
浮点数常常会比较大,数位非常多,为了阅读方便,程序中可能会使用一些不同的表示方法表示浮点数。最常规表示法是直接使用小数点表示浮点数。例如:3.14, 0.001, 4.0 等。 另一种常用的表示方法是科学计数法,使用 e 或 E 来表示 10 的指数。例如: 2.5e2 表示 ,1.23E-3 表示
特殊值
Python 的浮点数有几个特殊值: inf、-inf 和 nan,它们分别代表正无穷、负无穷和非数字值(Not a Number)。这些特殊值的存在是为了遵循 IEEE 754 浮点数标准。
这些特殊值的运算遵循如下规则:
inf + 任何正数 = inf inf - 任何正数 = inf -inf + 任何负数 = -inf -inf - 任何负数 = -inf inf + -inf = nan (正无穷加负无穷是未定义的,所以结果是nan) inf * 0 = nan (无穷乘以 0 是未定义的)
比如下面的程序:
positive_infinity = float("inf")
negative_infinity = float("-inf")
print(positive_infinity + negative_infinity) # 输出 nan
在上面的程序里 float() 是一个函数,用于将字符串或其他数值转换为浮点数,比如:
print(float(7)) # 输出 7.0
print(float("3.14")) # 输出 3.14
误差
浮点数的计算可能会导致一些舍入误差。这是由于计算机内部使用二进制浮点数表示法,某些十进制小数不能精确地表示为二进制小数。例如:
print(0.1 + 0.2) # 输出 0.30000000000000004 而不是 0.3
由于这种舍入误差,对浮点数进行相等性测试时需要特别小心。通常建议使用某个小的容差值,而不是直接比较两个浮点数是否完全相等。
更复杂的数学运算
除了基本的算术运算外,Python 还提供了许多内置函数来支持数值计算,如 abs(), round(), max(), min(), sum() 等。这些函数都是比较直观的,与数据运算中使用的函数保持一致,一看名字就知道它们是做什么的。例如:
print(abs(-5)) # 输出 5,表示绝对值计算
print(round(2.65)) # 输出 3,表示四舍五入的值
Python 还支持复数运算和一些更高级的数学函数,使其成为处理数学问题的强大工具。在科学计算、数据分析等领域,Python 尤其受欢迎,部分原因是因为它的这种灵活性和强大的数学运算能力。Python 的复杂数学函数多在自带的 math 和 statistics 标准库中,后文会对它们做详细介绍。这里先列出一个简单示例,比如要计算2.3 的平方根,可以调用 sqrt 函数:
import math
print(math.sqrt(2.3)) # 输出 1.51657508881031
复数 (Complex Numbers)
复数包含实部和虚部,虚部后面通常有一个“j”或“J”。比如:
print((3 + 4j) + (2 - 3j)) # 输出 5 + j
print((3 + 4j) - (2 - 3j)) # 输出 1 + 7j
print((3 + 4j) * (2 - 3j)) # 输出 18 - 1j
print((3 + 4j) / (2 - 3j)) # 输出 -0.46153846153846156 + 1.3076923076923077j
Python 自带的 math 标准库中的函数是用于实数运算的,不能用于复数运算。复数运算可以调用相应的 cmath 库中的相应函数。比如计算 2+3j 的平方根:
import cmath
print(cmath.sqrt(2+3j)) # 输出 (1.6741492280355401+0.8959774761298381j)
布尔值 (Booleans)
布尔值只有两种可能,即 True 和 False。它们实际上是整数的子类型,其中 True 为 1,False 为 0。
数据比较
在 Python 中,比较数值大小,是否相等的操作,会返回一个布尔值结果。以下是进行数值大小比较的常用运算符:
大于号 > 检查左边的值是否大于右边的值;小于号 < 检查左边的值是否小于右边的值;大于或等于号 >= 检查左边的值是否大于或等于右边的值;小于或等于 <= 检查左边的值是否小于或等于右边的值;等于 == 检查两个值是否相等; 不等于 != 检查两个值是否不相等。下面是一些示例:
print(5 > 3) # 输出 True
print(2 < 8) # 输出 True
print(7 >= 7) # 输出 True
print(4 <= 10) # 输出 True
print(6 == 6) # 输出 True
print(5 != 5) # 输出 False
编程序时,最容易出现的一个错误就是在判断两个数是否相等时,把相等检查的双等号 ==,写成赋值用的单等号 =。不过 Python 还好,通常会报告这样的错误,不像某些语言会悄无声息继续执行错误代码。
这些比较运算符不仅可以用于数值类型(整数、浮点数等),还可以用于其他可比较的数据类型,例如字符串、列表和其他序列类型。当比较这些非数值类型时,Python 通常使用字典序(也称为词典顺序)来确定顺序。
例如,在比较字符串时,"apple" < "banana" 的结果是 True,因为在字典中 "apple" 出现在 "banana" 之前。
需要注意 的是,进行数值比较时应确保参与比较的是同一类型或者是可以直接比较的类型。尽管 Python 通常可以自动在不同的数值类型之间进行转换(例如,在整数和浮点数之间),但在某些情况下,直接比较可能会导致不可预期的结果。
链式比较
有时候,我们可以使用一种非常直观的方式来进行多个条件的比较,也就是链式比较。比如,我们需要判断 x > 1 并且 x < 2 ,那么可以直接写成 1 < x < 2。这种链式比较的工作原理是:Python 会按照从左到右的顺序评估每个比较操作。比如对于 1 < x < 2,会首先会检查 1 < x 是否为真。如果为真,接着检查 x < 2。只有当这两个条件都为真时,整个表达式才会返回真。如果任何一个条件失败,则整个表达式立即返回假。
我们可以使用任何比较运算符,比如大于(>)、小于等于(<=)、大于等于(>=)等,来构建类似的链式比较。这种方式也不仅限于两个条件的比较,例如,a < b < c < d 也是完全有效的,它会检查 b 是否大于 a 且小于 c,以及 c 是否小于 d。比如:
x = 21
y = 25
print(20 < x < y < 30) # 输出 True
除了比较大小,其它一些运算符可以用在链式比较中,比如这个使用列表的例子,但那样通常会降低程序可读性,不推荐使用。
浮点数相等判断
由于浮点数的表示和计算可能导致微小的舍入误差,直接使用等于运算符 == 来判断两个浮点数是否相等可能会得到预料之外的结果。例如,计算 0.1 + 0.2 的结果并不完全等于 0.3,因为存在小的浮点舍入误差。
为了准确地判断两个浮点数是否"相等",一种常用的方法是判断两数之间的差值是否小于某个非常小的值(通常称为"容差"或"epsilon")。
以下是一个简单的示例,说明如何使用这种方法判断两个浮点数是否相等:
epsilon=1e-9
x = 0.1 + 0.2
y = 0.3
print(x == y) # 输出 False
print(abs(x - y) < epsilon) # 输出 True
在上面的示例中,abs() 还一个函数,它可以返回输入数据的绝对值。比较的逻辑是:如果 x 和 y 之间的差值小于 epsilon,则认为它们是"相等"的。选择合适的 epsilon 值是很重要的。对于大多数应用场景,1e-9 或 1e-12 通常足够了。