《从问题到程序:用Python学编程和计算》——2.2 数据对象、计算和类型

简介:

本节书摘来自华章计算机《从问题到程序:用Python学编程和计算》一书中的第2章,第2.2节,作者 裘宗燕,更多章节内容可以访问云栖社区“华章计算机”公众号查看。

2.2 数据对象、计算和类型

前面介绍了Python中可以表示和处理的几种数——整数、浮点数和复数,它们都是数学里的某类数的对应物,可以对它们做各种数学运算(用运算符描述),得到运算的结果。这些数都是程序操作的对象。

2.2.1 对象和类型

虽然整数、浮点数都是数,可以使用同样的运算符,但对数值相同的整数和浮点数做同样计算时,由于采用的规则不同,得到的结果也不同。例如:

>>> 12**30
237376313799769806328950291431424
>>> 12.0**30.0
2.373763137997698e+32

整数计算将得到任意大的准确结果,浮点数计算得到有限精度的近似结果。[ 在Python里,一定范围内的整数通过硬件直接实现,计算效率高。超范围的整数计算通过软件技术模拟,运算可能耗费较多时间。另一方面,浮点数采用硬件实现的计算,统一而高效。]

Python语言把在程序运行中能使用和处理的各种实体统称为对象(object),一个整数是一个对象,一个浮点数也是一个对象。在处理整数或浮点数字面量时,解释器创建相应的整数对象或浮点数对象,而计算也就是从一些对象算出另一些对象。在交互方式下,解释器把计算得到的结果对象显示出来给人看。

不同对象可能具有不同的性质。Python把性质相同、可以使用同一组操作、采用同样计算规则的一集对象称为一个类型。对属于同一类型的对象,解释器采用同样的处理方式。例如,整数就是一个类型,浮点数是另一个类型,复数又是另一个不同的类型。这几个类型有各自的字面量写法、可用运算的集合和运算规则。人们经常把整数类型简称为整型,把浮点数类型简称为浮点型。后面有时也这样说。

Python中的每个类型有一个名字(类型名),可以用特殊的方法得到:

>>> type(100)
<class 'int'>
>>> type(100.0)
<class 'float'>
>>> type(100+0j)
<class 'complex'>

第一个结果 表示字面量100描述的整数对象属于名字为int的类型,其他结果的意义类似。每个类型都有一个名字,称为类型名。整数类型的名字是int,浮点数的类型名是float,而复数的类型名是complex。对于任何描述对象的表达式,都可以用type取得其计算结果的类型:

>>> type(100 + 200)
<class 'int'>
>>> type(1.27 * 2.8)
<class 'float'>

int、float和complex统称为数值类型(numerical type)。这几个数值类型都是Python语言预先定义的类型,称为内置类型或者标准类型。

2.2.2 混合类型计算和类型转换

对数值类型的对象,Python允许做混合类型计算,也就是说,允许在一个表达式里出现不同数值类型的对象。例如:

>>> 2.7 * 3
8.100000000000001
>>> (2 + (1 + 3.4j)) * (5.78 - 3)
(8.34+9.452j)

自然,最后一个表达式得到的是复数类型的结果(对象)。

整数和浮点数各有自己的乘法运算规则,两者的运算规则不同。为了完成两个不同类型的对象之间的运算,Python严格规定了采用的规则。在这里的规定是:如果遇到表达式要求做一个整数和一个浮点数的运算,那么就先从那个整数转换得到一个“与之等值”的浮点数对象,而后再按浮点数的规则计算,得到浮点数结果。如果是整数(或浮点数)与复数运算,就先从该数转换得到一个复数,然后再计算。注意,这里说转换,术语是类型转换,实际上原来的数并不改变,而是根据该数按规则做出另一个满足需要的数。

上面的“与之等值”加了引号,是想说明这个说法并不准确。整数可以任意大,具有任意位精度。用浮点数表示,或许能表示其近似值(因此并不与之等值),甚至无法表示它(由于整数太大而溢出)。这是混合类型计算中可能出现的情况,必须注意。

总结一下:对混合类型的计算表达式,Python解释器将自动安排适当的转换,使表达式描述的计算得以进行。这种转换是解释器自动完成的操作,从已有的某类型对象出发,做出一个与之相关的具有所需类型的对象。在上面第二个例子里,先根据2做出一个复数,再用它与复数(1+3.4j)相加;再从整数3做出一个浮点数并从5.78里减去它;再从第二个计算的结果(一个浮点数)做出一个复数并完成两个复数的乘法。可见,要理解复杂表达式的意义,不仅要关注其中的计算如何进行,还要注意哪些地方出现了类型转换,各为从什么类型转到什么类型,具体计算是在哪个类型里进行的。

有时,自动完成的转换不符合实际计算的需要。出现这种情况时,我们就需要在表达式里说明期望的转换,相应描述称为强制类型转换。强制类型转换通过类型名描述,描述形式与前面写type的形式类似。例如:

>>> int(2.37**5.6) * 4
500

这里int(2.37**5.6)要求把浮点数计算的结果转换为整数,然后用它乘以4得到整数结果。用int将浮点数转换到整数的规则是丢掉小数,取得整数部分。

如果写表达式float(12**20),可以得到括号里整数计算结果的浮点数近似值。但Python不允许用float或int去转换复数对象,数学里也没有相应的规则。如果对不能转换的对象做转换,解释器也会报告错误。例如:

>>> float((2 + 1.2j)**3)
Traceback (most recent call last):
  File "<pyshell#69>", line 1, in <module>
    float((2 + 1.2j)**3)
TypeError: can't convert complex to float

取得复数的实部、虚部或者模的问题在后面说明。

类型名complex可用于构造复数:

>>> complex(12**20, 1.25**20)
(3.833759992447475e+21+86.73617379884035j)

括号里逗号分隔的两个表达式分别表示要构造的复数的实部和虚部。

最后考虑一个实际应用题:已知三角形的三边长度分别为5、7和11厘米,现在希望求出这个三角形的面积。

显然,为完成这个任务,首先需要找到从三边长求面积的方法。数学知识已经给出了相应的面积公式:

image

其中s是三角形的半周长,。根据这些公式,不难写出下面表达式:

>>> ((5 + 7 + 11)/2 * ((5 + 7 + 11)/2 - 5) *
 ((5 + 7 + 11)/2 - 7) * ((5 + 7 + 11)/2 - 11)) ** 0.5
12.968712349342937

为了写出这个长表达式,我们特别在前面多写了一个括号。在表达式换行时,因为有括号没配对,解释器自动把后一行当作续行。显然,这个表达式虽然解决了问题,但其形式不太令人满意,其中出现繁琐的重复。2.5节将解决这个问题。

2.2.3 数值类型和计算的简单总结

现在对本章中至此有关数值类型计算的讨论做一点总结。

Python语言提供了三个基本数值类型:int、float和comlex,规定了各种数字面量的描述形式,以便人们直接描述计算中使用的数值对象。Python的整数对象可以表示任意大的整数值,但浮点数(和复数)只能表示有限范围内精度有限的数值。

表示数值计算的表达式基于数值字面量、算术运算符和括号描述,形式上是一维的单词序列,序列中的单词和序列的构成形式都必须满足表达式的语法要求。满足规定(满足语法)的表达式才有意义(语义)。Python严格规定了单词和表达式的形式,所采用的形式解释器容易处理,人可以接受和习惯。遇到不合法的单词,或者构成形式不合法的表达式,解释器将报错,并能标明发现错误的位置。

合法的表达式描述了一个计算过程。如果解释器处理一个表达式的计算能顺利完成,就会求出该表达式的值。但是,满足语法的表达式在计算中也可能出错,如3/0、3.0/0.0在计算中就会报告除以0的动态运行错误。此外,浮点数运算的结果可能超出浮点数的表示范围,这种情况称为溢出。出现溢出时得到一个特殊结果。

表达式描述的求值过程由多方面的因素确定:运算符有优先级和结合方式,高优先级的运算符先执行,相同优先级的运算符按结合顺序执行。如果由优先级和结合方式默认确定的计算顺序不合适,可以加入括号明确指定所需计算顺序。

算术运算符分为一元运算符(正负号)和二元运算符,对二元运算符,在做它所要求的计算之前,总是先计算其左边的运算对象,再计算右边的运算对象。

参与计算的对象都有类型,计算的结果也有类型,对象的类型决定计算的方式和结果。两个同样类型的数值对象直接参与运算,运算结果一般也具有同样类型(整数除法运算符 / 的情况特殊,其结果是浮点数)。用type可以得到表达式的计算结果的类型(注意,字面量是最简单的表达式)。

如果参与一个二元运算的两个对象的类型不同,解释器先把它们转换为同样类型后再计算。整数与浮点数或复数运算,解释器自动由它做出一个浮点数或复数;浮点数与复数运算,解释器自动由这个浮点数做出一个复数。如果混合类型计算中的自动转换不合乎需要,可以人工描述转换。用类型名int可以构造与给定浮点数对应的整数值(取整)。

应特别注意,做数值转换时可能出错。在把一个整数转换为一个浮点数时,得到的结果可能超出浮点数的表示范围。还需注意,整数计算是精确计算,总得到精确的整数结果(除了使用运算符 / 的情况),浮点数计算和复数计算是近似计算,总得到近似结果,计算中可能出现误差,需要特别当心。这个问题后面还会讨论。

相关文章
|
2月前
|
数据采集 Web App开发 数据可视化
Python零基础爬取东方财富网股票行情数据指南
东方财富网数据稳定、反爬宽松,适合爬虫入门。本文详解使用Python抓取股票行情数据,涵盖请求发送、HTML解析、动态加载处理、代理IP切换及数据可视化,助你快速掌握金融数据爬取技能。
1566 1
|
2月前
|
存储 JavaScript Java
(Python基础)新时代语言!一起学习Python吧!(四):dict字典和set类型;切片类型、列表生成式;map和reduce迭代器;filter过滤函数、sorted排序函数;lambda函数
dict字典 Python内置了字典:dict的支持,dict全称dictionary,在其他语言中也称为map,使用键-值(key-value)存储,具有极快的查找速度。 我们可以通过声明JS对象一样的方式声明dict
225 1
|
2月前
|
Java 数据挖掘 数据处理
(Pandas)Python做数据处理必选框架之一!(一):介绍Pandas中的两个数据结构;刨析Series:如何访问数据;数据去重、取众数、总和、标准差、方差、平均值等;判断缺失值、获取索引...
Pandas 是一个开源的数据分析和数据处理库,它是基于 Python 编程语言的。 Pandas 提供了易于使用的数据结构和数据分析工具,特别适用于处理结构化数据,如表格型数据(类似于Excel表格)。 Pandas 是数据科学和分析领域中常用的工具之一,它使得用户能够轻松地从各种数据源中导入数据,并对数据进行高效的操作和分析。 Pandas 主要引入了两种新的数据结构:Series 和 DataFrame。
468 0
|
2月前
|
JSON 算法 API
Python采集淘宝商品评论API接口及JSON数据返回全程指南
Python采集淘宝商品评论API接口及JSON数据返回全程指南
|
2月前
|
JSON API 数据安全/隐私保护
Python采集淘宝拍立淘按图搜索API接口及JSON数据返回全流程指南
通过以上流程,可实现淘宝拍立淘按图搜索的完整调用链路,并获取结构化的JSON商品数据,支撑电商比价、智能推荐等业务场景。
|
2月前
|
Python
Python编程:运算符详解
本文全面详解Python各类运算符,涵盖算术、比较、逻辑、赋值、位、身份、成员运算符及优先级规则,结合实例代码与运行结果,助你深入掌握Python运算符的使用方法与应用场景。
230 3
|
2月前
|
数据处理 Python
Python编程:类型转换与输入输出
本教程介绍Python中输入输出与类型转换的基础知识,涵盖input()和print()的使用,int()、float()等类型转换方法,并通过综合示例演示数据处理、错误处理及格式化输出,助你掌握核心编程技能。
484 3
|
2月前
|
并行计算 安全 计算机视觉
Python多进程编程:用multiprocessing突破GIL限制
Python中GIL限制多线程性能,尤其在CPU密集型任务中。`multiprocessing`模块通过创建独立进程,绕过GIL,实现真正的并行计算。它支持进程池、队列、管道、共享内存和同步机制,适用于科学计算、图像处理等场景。相比多线程,多进程更适合利用多核优势,虽有较高内存开销,但能显著提升性能。合理使用进程池与通信机制,可最大化效率。
310 3
|
3月前
|
数据采集 关系型数据库 MySQL
python爬取数据存入数据库
Python爬虫结合Scrapy与SQLAlchemy,实现高效数据采集并存入MySQL/PostgreSQL/SQLite。通过ORM映射、连接池优化与批量提交,支持百万级数据高速写入,具备良好的可扩展性与稳定性。

推荐镜像

更多