前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >《Python完全自学教程》免费在线连载3.3.2

《Python完全自学教程》免费在线连载3.3.2

作者头像
老齐
发布2022-04-01 10:03:09
1.3K0
发布2022-04-01 10:03:09
举报
文章被收录于专栏:老齐教室

3.3.2 标准库的数学模块

Python 的发明者吉多·范罗苏姆说:Python 有“自带电池”的理念,从它的庞大软件包复杂而又可靠的能力中可见端倪(英文:Python has a "batteries included" philosophy. This is best seen through the sophisticated and robust capabilities of its larger packages.参阅:https://en.wikipedia.org/wiki/Standard_library)。所谓“自带电池”就是指 Python 标准库(Python Standard Library,官方文档地址是 https://docs.python.org/3/library/index.html),标准库的有关程序在安装本地 Python 开发环境时已经随之安装好,与内置函数类似,也能“开箱即用”。

Python 标准库非常庞大,此处仅介绍与初等数学计算相关的模块(更多内容,参阅第11章11.3节)。

1. math 模块

标准库中的 math 模块主要提供初等数学中常用函数,官方文档地址是 https://docs.python.org/3/library/math.html。请在本地交互模式中,输入 import math ,然后敲回车键,如下所示:

代码语言:javascript
复制
>>> import math    # (1)
>>>

输入注释(1)并敲回车键后,光标停在了下一行,且没有任何返回内容——关键是没有报错,这说明本地已经正确安装了 math 模块。注释(1)的作用是将标准库中的 math 模块引入到当前环境——标准库不是内置函数,其模块都必须用关键词 import 引入之后才能使用(参阅第11章11.1节)。

接着注释(1),继续执行如下操作:

代码语言:javascript
复制
>>> dir(math)
['__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atan2', 'atanh', 'ceil', 'comb', 'copysign', 'cos', 'cosh', 'degrees', 'dist', 'e', 'erf', 'erfc', 'exp', 'expm1', 'fabs', 'factorial', 'floor', 'fmod', 'frexp', 'fsum', 'gamma', 'gcd', 'hypot', 'inf', 'isclose', 'isfinite', 'isinf', 'isnan', 'isqrt', 'lcm', 'ldexp', 'lgamma', 'log', 'log10', 'log1p', 'log2', 'modf', 'nan', 'nextafter', 'perm', 'pi', 'pow', 'prod', 'radians', 'remainder', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'tau', 'trunc', 'ulp']

这里使用了内置函数 dir() ,它能够返回参数对象的属性和方法——在第2章2.4节初步接触了对象的“属性”和“方法”,更详细的内容请参阅第8章。对于 dir(math) 的返回结果,也可以理解为模块 math 里面提供的函数。不妨浏览一番这些函数名称,并与记忆中的初等数学常用函数对比,是不是觉得这里已经基本涵盖了常用的函数呢?

这些函数怎么用?以余弦函数 cos 为例,根据自学经验,应该先看一看这个函数的文档:

代码语言:javascript
复制
>>> help(math.cos)

注意上述写法,不能直接写 help(cos) ,因为函数 cos 是模块 math 的一员,注释(1)引入的是这个模块,当调用其中的函数时,必须借助模块的名称(可用图3-3-4所示帮助记忆和理解。这是调用模块内函数的一种方式,更多内容参阅第11章11.1节)。

图3-3-4 调用模块里的函数

执行上述语句,可以看到 math.cos 的帮助文档:

代码语言:javascript
复制
cos(x, /)
    Return the cosine of x (measured in radians).
代码语言:javascript
复制
>>> alpha = 60 / 180 * math.pi    # (2)
>>> math.cos(alpha)               # (3)
0.5000000000000001
代码语言:javascript
复制
>>> math.pi
3.141592653589793
代码语言:javascript
复制
>>> round(math.cos(math.pi/4) + math.log10(5) * math.exp(2), 2)
5.87

2. fractions 模块

在前面的代码演示中,注释(2)只能将分数计算为浮点数实现近似计算,如何才能实现精确地表示

\frac{60}{180}=\frac{1}{3}

呢?这就是标准库中的 fractions 模块所要解决的问题。

代码语言:javascript
复制
>>> import fractions                  # (4)
>>> a = fractions.Fraction(60, 180)   # (5)
>>> a
Fraction(1, 3)

注释(4)引入模块 fractions ,注释(5)使用 fractions.Fraction() 创建分数——注意大小写,其参数中的第一个 60 是分数的分子,第二个 180 是分数的分母,即

\frac{60}{180}

。返回值是 Fraction(1, 3) ,表示分数

\frac{1}{3}

。由此可见,注释(5)创建分数的时候,会自动化简,以最简分数作为结果。

代码语言:javascript
复制
>>> 1 / 3 + 1 / 2
0.8333333333333333

这是用浮点数形式计算

\frac{1}{3} + \frac{1}{2}

的结果,现在可以这样做:

代码语言:javascript
复制
>>> b = fractions.Fraction(1, 2)
>>> a + b
Fraction(5, 6)

如此就实现了分数的精确计算。

除了用注释(5)创建分数之外,还有其他的创建方式,此处不再赘述,请读者自行参考官方文档(https://docs.python.org/3/library/fractions.html)中的示例。下面要对注释(2)和(3)重新计算,用分数得到精确结果。

代码语言:javascript
复制
>>> alpha = fractions.Fraction('60/180') * math.pi            # (6)
>>> fractions.Fraction(math.cos(alpha)).limit_denominator()   # (7)
Fraction(1, 2)

先看结果,得到了

\cos\left(\frac{1}{3}\pi\right)

的精确结果

\frac{1}{2}

。不过,注释(6)中使用了另外一种创建分数的方法——参数形式与(5)不同(建议读者参阅官方文档示例)。注释(7)比较长,可以分为两部分,第一部分是 fractions.Fraction(math.cos(alpha)) ,这其实是第三种创建分数的方法——参数是浮点数。

代码语言:javascript
复制
>>> fractions.Fraction(0.5)
Fraction(1, 2)

如注释(3)所示,math.cos(alpha)的值是一个浮点数,再以它为参数,创建分数:

代码语言:javascript
复制
>>> fractions.Fraction(math.cos(alpha))    # (8)
Fraction(4503599627370497, 9007199254740992)

注意,math.cos(alpha) 的浮点数结果并非严格等于 0.5(如注释(3)的返回值所示),因此在注释(8)中看到所得分数只能很接近于 Fraction(1, 2) 。为此,注释(7)调用了该对象的方法 limit_denominator() ,它的作用是返回最近似的分数——需要注意此方法的默认参数 max_denominator=1000000 ,最近似的分数是以此分母计算,例如:

代码语言:javascript
复制
>>> fractions.Fraction('3.1415926535897932').limit_denominator(1000)
Fraction(355, 113)
>>> fractions.Fraction('3.1415926535897932').limit_denominator(100)
Fraction(311, 99)
>>> fractions.Fraction('3.1415926535897932').limit_denominator(10)
Fraction(22, 7)

当然,此处所创建的分数,也可以和浮点数、整数进行算术运算,或者作为函数的参数。

代码语言:javascript
复制
>>> a
Fraction(1, 3)
>>> a + 2
Fraction(7, 3)
>>> a + 0.5
0.8333333333333333
>>> a ** 2
Fraction(1, 9)
>>> pow(a, 3)
Fraction(1, 27)
>>> math.sin(a)
0.3271946967961522

问题来了,既然用分数对象能够精确计算,还要浮点数有什么用?有用!在 Python 中,运算 float 类型的对象要比运算 fractions.Fraction 类型的对象速度快,并且在一般情况下,浮点数运算的精度已经足够了。如果不是“一般情况”呢?就“鱼和熊掌不可兼得”,只能忍受“速度慢”了吗?也不是。Python 是一个开放的生态系统,除了标准库之外,还有更庞大的“第三方库”(参阅第11章),其中就有解决此问题的模块,比如 quicktions —— “日光之下,并无新事”,倘若真的找不到满足需要的工具,那就是创新的机遇,一定要抓住。

针对本节内容,建议读者自己设计一些计算题进行练习——可以帮助中小学生解题。

这里暂介绍标准库中与数学计算有关的两个模块,在后续学习中还会遇到其他模块,第11章就此有专门介绍。

自学建议 本节的学习中,使用了“帮助文档”和“官方文档”,这些文档是关于编程语言的最权威资料。但是,如何使用这些文档,是一个需要探讨的问题。以下是我的个人经验,供读者参考:

  • 将文档当做《新华字典》那样的工具,有问题时去查询。一般地,语文学科的主要学习资料是课本,字典是必不可少的辅助学习的工具。但很少有人用《新华字典》来学习语文。有人号称“看文档就能掌握编程语言”,他一定是聪明人。
  • 如果文档的原初语言是英文,尽可能看英文的文档(虽然有的文档翻译为中文了,但有的翻译并没有体现本意)。在第1章1.6节的【自学建议】中已经就本书引用英文文档的问题给予了解释说明,这里再次强调,旨在避免读者误解。凡是有志于自学,并以成为某领域翘楚为目标者,均不会畏惧各类文档中的英文。

在本书后续内容,我会经常提醒读者查看文档,根据以往经验,会有的学习者对此破不耐烦——曾有学习者在我的课程中对这种建议给予了“狂喷”。但我不会由于他的不满而改变此风格,真正有追求的读者能理解我的建议和要求。”

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-03-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 老齐教室 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 3.3.2 标准库的数学模块
相关产品与服务
对象存储
对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档