【Python 学习手册笔记】数字

来源:互联网 发布:如何看懂经济数据 编辑:程序博客网 时间:2024/05/11 00:49


第五章 数字

Python 的数字类型
Python数字类型的完整工具包括:
 整数和浮点数
 复数
 固定精度的十进制数
 有理分数
 集合
 布尔类型
 无穷的整数精度
 各种数字内置函数和模块

表5-1 :墓本数字常量
数字常量
1234, -24, 0.99999999999999              整数(无穷大小)
1.23, 1., 3.14e-10, 4E210, 4.0e+210     浮点数
0177, 0X9ff, 0b101010                          Python 2.6中的八进制、十六进制和二进制常量
0o177, 0X9ff, 0b101010                        Python 3.0中的八进制、十六进制和二举制常量
3+4j, 3.0+4.0j, 3j                                   复数常量


复数常量
整数和浮点数常量:
整数以十进制数字的字符串写法出现。浮点数带一个小数点,也可以加上一个科学计数标志e或者E。如果编写一个带有小数点或幕的数字. Python会将它变成一个浮点数对象,并且当这个对象用在表达式中时,将启用浮点数(而不是整数)的运算法则。
十六进制数以0x或0x开头,后面接十六进制的数字0-9和A-F;八进制数常量以数字0o或0O开头(0和小写或大写的字母"。"),后面接着数字0-7构成的字符
串;二进制常量,以0b或0B开头,后面跟着二进制数字(0-1)。

注意所有这些常量在程序代码中都产生一个整数对象,它们仅仅是特定值的不同语法表示而已。内置函数hex(I) 、oct(I)和bin(I)把一个整数转换为这3种进制表示的字符串,并且int(str,base)根据每个给定的进制把一个运行时字符串转换为一个整数。


复数
Python的复数常量写成实部+虚部的写法,这里虚部是以j或J结尾。其中,实部从技术上讲可有可无,所以可能会单独表示虚部。从内部看来,复数都是通过一对浮点数来表示的,但是对复数的所有的数字操作都会按照复数的运算法则进行。也可以通过内置函数complex(real,imag)来创建复数。

编写其他的数字类型
我们将在本章后面看到,还有表5-1中所没有包含的其他的、更高级的数字类型。其中的一些通过调用导入的模块中的函数来创建(例如,十进制数和分数) ,其他的一些拥有它们自己的常量语法(例如,集合)。

内置数学工具和扩展:
表达式操作符
+、-, * 、/、>>、**、&等。

内置数学函数
pow 、abs 、round 、int 、hex 、bin等。

公用模块
random 、math等。


Python表达式操作符
表达式是处理数字的最基本的工具。当一个数字(或其他对象)与操作符相结合时,Python执行时将计算得到一个值。在Python 中,表边式是使用通常的数学符号和操作符号写出来的。

表5-2: Python表达式操作符及程序
操作符                                                         描述
yield x                                                         生成器函数发送协议
lambda args: expression                            生成匿名函数
x if Y else z                                                 三元选择表达式
x or y                                                           逻辑或(只有x为假,才会计算y)
x and y                                                        逻辑与(只有x为真,才会计算y )
not x                                                            逻辑非
x in y, x not in y                                           成员关系(可选代对象、集合)
x is y, x is not y                                           对象实体测试
x < y, x <= y, x > y, x >= y                          大小比较,集合子集和超集值相等性操作符
x == y, x != Y
x | y                                                             位或,集合并集
x ^ y                                                            位异或,集合对称差
x & Y                                                           位与,集合交集
x << y, x >> y                                              左移或右移y位
x + y, x - y                                                   加法/合并,减泣,集合差集
x * y, x % y, x / y, x // Y                               乘法/重复,余数/格式化,除法:真除在去或floor除法
-x, +x                                                          一元减法,识别
~x                                                               按位求补(取反)
x ** y                                                           幂运算
x[i]                                                               索引(序列、映射及其他)点号取属性运算,函数调用
x[i:j:k]                                                          分片
x(...)                                                            调用(函数、方法、类及其他可调用的)          
x.attr                                                           属性引用              
(...)                                                              元组,表达式, 生成器表达式
[...]                                                              列表,列表解析
{...}                                                             字典、集合、集合和字典解析


在表5-2 中,表的操作符中越靠后的优先级越高;
is操作符测试对象身份(也就是内存地址,严格意义上的相等);

混合类型自动升级
在混合类型的表达式中, Python首先将被操作的对象转换成其中最复杂的操作对象的类型,然后再对相同类型的操作对象进行数学运算。如果你使用过C语言,你会发现这个行为与C语言中的类型转换是很相似的;Python是这样划分数字类型的复杂度的:整数比浮点数简单,浮点数比复数简单。要记住所有这些混合类型转换仅仅在将数字类型(例如,一个整数和一个浮点数)混合到一个表达式中的时候才适用,这包括那些使用数字和比较操作符的表达式。
一般来说, Python不会在其他的类型之间进行转换。


运算符重载:
所有的Python操作符可以通过Python的类或C扩展类型被重载(即实现),让它也能工作在你所创建的对象中。例如,用类编写的对象代码也许可以使用+表达式做加法或连接,以及使用[i] 表达式进行索引等。
Python 自身自动重载了某些操作符,能够根据所处理的内置对象的类型而执行不同的操作。例如,"+"操作符应用于数字时是在做加法,而用于字符串或列表这样的序列对象时是在做合并运算。实际上,“+” 应用在定义的类的对象上可以进行任何运算。
这种特性通常称作多态。这个术语指操作的意义取决于所操作的对象的类型。

str和repr显示格式
从技术土来说,默认的交互模式回显和打印的区别就相当于内置repr和str函数的区别;

>>> from __future__ import division
>>> 10 / 4
2.5
>>> 10 // 4
2

eval 函数,将会把字符串作为Python代码:
>>> eval('64'),eval('0o100'),eval('0x40'),eval('0b10000')
(64, 64, 64, 64)

使用字符串格式化方法调用和表达式将一个整数转换成八进制数和十六进制数的字符串:
>>>  '{0:o}, {1:X}, {2:b}'.format(64, 64, 64)
100, 40, 1000000
>>> '%o, %x, %X' % (64, 255, 255)
-100, ff, FF'

其他的内置数学工具
除了核心对象类型以外. Python还支持用于数字处理的内置函数和内置模块。例如,内置函数pow和abs. 分别计算幕和绝对值。这里有一些内置math模块
>>> import math
>>>math.pi, math.e
(3.1415926535897931, 2.7182818284590451)

在Python中有3种方泣可以计算平方根:使用一个模块函数、一个表达式或者一个内置函数:
>>> import math
>>> math.sqrt(144)
12.0
>>> 144 ** .5
12.0
>>> pow(144, .5)
12.0

注意内置math这样的模块必须先导入,但是abs这样的内置函数不需要导入就可以直接使用。换句话说,模块是外部的组件,而内置函数位于一个隐性的命名空间内,Python自动搜索程序的变量名。这个命名空间对应于Python3.0中名为builtins的模块(Python2.6中是builtin);


使用标准库中的random模块时必须导入。这个模块提供了工具,可以选出一个在0和1之间的任意浮点数、选择在两个数字之间的任意整数、在一个序列中任意挑选一项等;Random模块很实用,在游戏中的发牌、在演示GUI中随机挑选固片、进行统计仿真等都需要使用Random模块。


其他数字类型

小数数字:
基础知识:
浮点数学缺乏精确性,因为用来存储数值的空间有限。例如,下面的计算应该得到零,但是结果却没有。结果接近零,但是却没有足够的位数去实现这样的精度:
>>> 0.1 + 0.1 + 0.1 - 0.3
5.551115123125783e-17

使用小数对象,结果能够改正:
>>> from decimal import Decimal
>>> Decimal('0.1') + Decimal('0.1') + Decimal('0.1') - Decimal('0.3')
Decimal('0.0')

正如这里显示的,我们能够通过调用在decimal模块中的Decimal的构造函数创建一个小数对象,并传入一个字符串,这个字符串有我们希望在结果中显示的小数位数。当不同精度的小数在表达式中混编时, Python 自动升级为小数位数最多的:
>>> Decimal('0.1') + Decimal('0.10') + Decimal('0.10') - Decimal('0.30')
Decimal('0.00')

设置全局精度
decimal模块中的其他工具可以用来设置所有小数数值的精度、设置错误处理等。例如,这个模块中的一个上下文对象允许指定精度(小数位数)和舍入模式(舍去、进位等)。该精度全局性地适用于调用钱程中创建的所有小数:
>>> import decimal
>>> decimal.Decimal(1) / decimal.Decimal(7)
Decimal('0.1428571428571428571428571429')
>>> decimal.getcontext().prec
28
>>> decimal.getcontext().prec=4
>>> decimal.Decimal(1) / decimal.Decimal(7)
Decimal('0.1429')
>>> len(str(decimal.Decimal(1) / decimal.Decimal(7)))

小数上下文管理器
在Python 2.6和Python 3.0 (及其以后的版本中) ,可使用上下文管理器语句来重新设置临时精度。在语句退出后,精度又重新设置为初始值:
>>> import decimal
>>> decimal.Decimal('1.00') / decimal.Decimal('3.00')
Decimal('0.3333333333333333333333333333')
>>>
>>> with decimal.localcontext() as ctx:
...     ctx.prec = 2
...     decimal.Decimal('1.00') / decimal.Decimal('3.00')
...
Decimal('0.33')
>>>
>>> decimal.Decimal('1.00') / decimal.Decimal('3.00')
Decimal('0.3333333333333333333333333333')


分数类型
Python 2.6和Python 3.0引入了一种新的数字类型-分数,它实现了一个有理数对象。它明确地保留一个分子和一个分母,从而避免了浮点数学的某些不精确性和局限性。
分数以类似于小数的方式使用,它也存在于模块中;导入其构造函数并传递一个分子和一个分母就可以产生一个分数;
>>> from fractions import Fraction
>>> x = Fraction(1, 3)
>>> y = Fraction(4, 6)
>>>
>>> x
Fraction(1, 3)
>>> y
Fraction(2, 3)
>>> print(y)
2/3
>>> x + y
Fraction(1, 1)
>>> x - y
Fraction(-1, 3)
>>> x * y
Fraction(2, 9)

分数对象也可以从浮点数字符串来创建:
>>> Fraction('0.25')
Fraction(1, 4)

为了支持分数转换. 浮点数对象现在有一个方法,能够产生它们的分子和分母,分数有一个from float方法,并且float接受一个Fraction作为参数。
>>> (2.5).as_integer_ratio()
(5, 2)
>>> 2.5.as_integer_ratio()
(5, 2)
>>> f = 2.5
>>> z = Fraction(*f.as_integer_ratio())
>>> z
Fraction(5, 2)

>>> x
Fraction(1, 3)
>>> x + z
Fraction(17, 6)
>>> float(x + z)
2.8333333333333335
>>> Fraction.from_float(1.75)
Fraction(7, 4)

集合
集合(set),这是一些唯一的、不可变的对象的一个无序集合(collection),这些对象支持与数学集合理论相对应的操作。根据定义,一个项在集合中只能出现一次,不管将它添加了多少次;集合是可以选代的.可以根据需要增长或缩短,并且能够包含各种对象类型。我们将会看到,一个集合的行为很像一个无值的字典的键,但是,它还支持额外的操作。由于集合是无序的,并且不会把键匹配到值,它们既不是序列也不是映射类型;它们是自成一体的类型。

要创建一个集合对象,向内置的set 函数传递一个序列或其他的可迭代的对象:
>>> x = set('abcde')
>>> y = set('bdxyz')
>>> x
{'c', 'd', 'a', 'e', 'b'}
>>> y
{'z', 'd', 'y', 'x', 'b'}
>>> 'e' in x
True
>>> x - y
{'c', 'a', 'e'}
>>> x | y
{'c', 'y', 'z', 'd', 'e', 'b', 'x', 'a'}
>>> x & y
{'d', 'b'}
>>> x ^ y
{'c', 'y', 'z', 'e', 'x', 'a'}


除了表达式,集合对象还提供了对应这些操作的方法,以及更多的支持改变集合的方法,集合add方法插入一个项目、update是按位置求并集,remove根据值删除一个项目
>>>
>>> z = x.intersection(y)
>>> z
{'d', 'b'}
>>> z.add('SPAM')
>>> z
{'d', 'SPAM', 'b'}
>>> z.update(set(['X', 'Y']))
>>> z
{'Y', 'd', 'SPAM', 'b', 'X'}
>>> z.remove('b')
>>> z
{'Y', 'd', 'SPAM', 'X'}

作为可选代的容器,集合也可以用于len 、for循环和列表解析这样的操作中。然而,由于它们都是无序的,所以不支持像索引和分片这样的操作:

>>> for item in set('abc'):print(item * 3)
...
ccc
aaa
bbb

在Python 中{}仍然是一个字典。空的集合必须通过内置函数set来创建。

不可变限制和冻结集合
集合只能包含不可变的(即可散列的)对象类型。因此,列表和字典不能嵌入到集合中,但是,如果你需要存储复合值的话,元组是可以嵌入的. 集合本身也是不可改变的,因此,不能直接嵌入到其他集合中, 如果需要在另一个集合中存储一个集合,可以像调用set一样来调用frozenset. 但是,它创建一个不可变的集合,该集合不可修改并且可以嵌套到其他集合中。

集合解析:集合解析运行一个循环并在每次迭代时收集一个表达式的结果,通过一个循环变量采访问当前的迭代值以用于集合表达式中。结果是通过运行代码创建的一个新的集合,它具备所有一般的集合行为。
>>> {x ** 2 for x in [1, 2, 3 ,4]}
set([16, 1, 4, 9])


由于项在集合中只能存储一次,集合(set) 可以用来把重复项从其他集合(collection)中过滤掉。直接把集合(collection) 转换为一个集合(set) ,然后再转换回来即可(因为集合是可选代的,这里的list调用对其有效)
>>> L = [1, 2, 1, 3, 2, 4, 5]
>>> set(L)
set([1, 2, 3, 4, 5])
>>> L = list(set(L))
>>> L
[1, 2, 3, 4, 5]


布尔型
Python如今正式地有了一种明确的布尔型数据类型,叫做bool. 其值为True和False. 并且其值True和False是预先定义的内置的变量名。在内部,新的变量名True和False是bool的实例,实际上仅仅是内置的整数类型int的子类;

数字扩展
如果你需要做一些正式的数字计算,一个叫做NumPy (Numeric Python)的可选的Python扩展提供了高级的数字编程工具,例如矩阵数据类型、向量处理和高级的计算库;Python和NumPy的组合往往可以比作是一款免费的、更加灵活的Matlab,可以得到NumPy的性能以及Python语言及其库。

可以通过在Python的PyPI站点或者通过搜索Web,来找到对高级数字编程的其他支持,包括图形工具和绘制工具、统计库以及流行的SciPy包。


0 0
原创粉丝点击