古城热线 发表于 2018-8-9 09:43:25

Python回顾与整理3:数字

  0.说明
  数字用的次数是否多主要是看需求,如果是做自动化运维平台开发,比如做一个自动监控的系统,那么你肯定需要收集一定量的数据,然后再对这些数据做一定的处理,那么这时候,你就一定需要用得上数字的。当然,我这里所说的要不要用数字,指的是,你是否需要对你的数据做一定的处理。
  1.数字简介
  数字是不可更改类型,也就是说变更数字的值会生成新的对象。
  (1)创建数值对象并用其赋值(数字对象)
>>>anInt = 1  
>>>aComplex = 1.23+4.56j
  (2)更新数字对象
  因为数字对象是不可变对象,所以所谓的更新指的是:删除该变量原来指向的数字对象,同时生成一个新的数字对象并让该变量指向它。
>>> anInt = 1  
>>> id(anInt)
  
35934552
  
>>> anInt += 1
  
>>> anInt
  
2
  
>>> id(anInt)
  
35934528
  (3)删除数字对象
  只要数字对象的引用计数器为零,那么该数字对象本身就会被删除。
>>> del anInt  
>>> id(anInt)
  
Traceback (most recent call last):
  
File "<stdin>", line 1, in <module>
  
NameError: name 'anInt' is not defined
  2.整型
  Python的整型分为几种:布尔型标准整型长整型
  (1)布尔型
  取值范围只有True和False。
  (2)标准整型
  相当于是C的(有符号)长整型,八进制数以数字“0”开始,十六进制数以“0x”或“0X”开头。
  (3)长整型
  末尾加上字母“L”或“l”,但建议写成大写
  需要注意的是,在现在,Python的标准整型和长整型其实区分已经不明确了,已经不需要考虑是使用标准整型和长整型了,因为一旦有数据溢出的情况,Python将会自动为我们转换为长整型,即整型和长整型会慢慢统一。
  3.双精度浮点数
  Python中的浮点型类似C语言中的double类型,是双精度浮点型(即长浮点数),每个浮点型占8个字节,即64位,完全遵守IEEE745标准浮点数规范。(关于长浮点数的表示方法以及在计算机中的处理,可以参考计算机组成原理的相关书籍)
  下面是一些合法的表示方法:
>>> 0.0  
0.0
  
>>> -777.
  
-777.0
  
>>> 96e3 * 1.0
  
96000.0
  
>>> 4.3e25
  
4.3e+25
  
>>> 9.384e-23
  
9.384e-23
  
>>> float(12)
  
12.0
  
>>> 4.2E-10
  
4.2e-10
  4.复数
  一个复数是一对有序浮点型(x,
y),表示为x
+ yj,其中x是实数部分,y是虚数部分。有下面的注意点:

[*]  虚数不能单独存在,它们总是和一个值为0.0的实数部分一起来构成一个复数
[*]  复数由实数部分和虚数部分组成
[*]  表示虚数的语法:x+ yj
[*]  实数部分和虚数部分都是浮点型
[*]  虚数部分必须有后缀j或J
  根据上面的要点,要写出合法的复数就很简单了。
  (1)复数的内建属性
  主要是复数的实部,虚部以及它的共轭复数,如下:
>>> aComplex = 1.3 + 3j  
>>> aComplex.real
  
1.3
  
>>> aComplex.imag
  
3.0
  
>>> aComplex.conjugate()
  
(1.3-3j)
  5.操作符
  Python操作符主要是指三种:标准类型操作符 数值操作符和专门的整型操作符。
  (1)混合模式操作符
  主要是指,当两种类型不同的数值进行运算时,Python会根据相应的规则自动帮我们作类型的强制转换,而这些规则如下(其实就是coerce()方法的描述,后面会有介绍):

[*]  如果有一个操作数是复数,另一个操作数则被转换为复数
[*]  否则,如果有一个操作数是浮点型,另一个操作数被转换为浮点型
[*]  否则,如果有一个操作数是长整型,另一个操作数被转换为长整型
[*]  否则,两者必须都是普通整型,无须作类型转换
  (2)标准类型操作符
  在《Python回顾与整理2:Python对象》中,介绍了Python标准类型的操作符,这些标准类型操作符对数值类型也是适用的,举例如下:
>>> 1 == 1  
True
  
>>> 1 < 5 < 9
  
True
  
>>> 1 < 5 and 5 < 9
  
True
  (3)算术操作符
  这类操作符在许多编程语言中都有,如加
减 乘 除 取余和幂运算等等。部分介绍如下:
  (a)除法

[*]  传统除法
>>> 3 / 2  
1
  
>>> 1 / 2
  
0
  
>>> 1.0 / 2.0
  
0.5

[*]  真正的除法
>>> from __future__ import division  
>>> 1 / 2
  
0.5
  
>>> 1.0 / 2.0
  
0.5
  需要注意的是,__future__是Python提供新特性测试的一个包,对于可能会在以后支持的特性,Python都会将其归入这个包以供测试。

[*]  地板除
>>> 1 // 2  
0
  
>>> 1.0 // 2.0
  
0.0
  
>>> 3 // 2
  
1
  在Python3+版本中,除法已经是真正的除法了,而不是默认的地板除,当然,如果确定是要使用地板除的,只需要使用“//”就可以了。
  (b)取余
  比较简单:
>>> 5 % 2  
1
  (c)幂运算
  主要是幂运算操作符**,其优先级可描述如下:

[*]  比其左侧操作数的一元操作符优先级高
[*]  比其右侧操作数的一元操作符优先级低
  例子如下:
>>> 3 ** 2  
9
  
>>> -3 ** 2
  
-9
  
>>> 4.0 ** -1.0
  
0.25
  (4)位操作符(只适用于整型)
  Python整型支持标准位运算,主要是:

[*]  取反(~)
>>> ~2  
-3
  即结果为-(num
+ 1),从二进制角度的解释如下:
  2的二进制为:00000010
  按位取反后为:11111101
  因为Python中的数默认是有符号数,因此计算机在处理11111101时,认为它是一个负数(最高位为符号位),而负数在计算机中是以补码的形式表示的,因此,在输出11111101的十进制数之前,计算机将其转换为原码,即除符号位外其余各位取反加1,所以最后得到的是10000011,也就是-3了。(关于相关的理论知识,可以参考计算机组成原理的相关内容)

[*]  按位与(&)
>>> 2 & 3  
2
  2为0000|0010,3为0000|0011,按位与即为0000|0010,也就是2了。

[*]  或(|)
>>> 2 | 3  
3
  2为0000|0010,3为0000|0011,按位或即为0000|0011,也就是3了。

[*]  异或(^)
>>> 2 ^ 3  
1
  2为0000|0010,3为0000|0011,按位或即为0000|0001,也就是1了。

[*]  左移(<<)
>>> 2 << 1  
4
  2的二进制表示为0000|0010,左移一位即为0000|0100,也就是4了。

[*]  右移(>>)
>>> 2 >> 1  
1
  2的二进制表示为0000|0010,右移一位即为0000|0001,也就是1了。
  6.内建函数与工厂函数
  (1)标准类型函数
  在《Python回顾与整理2:Python对象》中,介绍了Python标准类型的内建函数,这些标准类型的内建函数对数值类型也是适用的,举例如下:
>>> cmp(1, 3)  
-1
  
>>> cmp(0xff, 255)
  
0
  
>>> str(0xff)
  
'255'
  
>>> str(55.3e2)
  
'5530.0'
  
>>> type(0xFF)
  
<type 'int'>
  
>>> type(314L)
  
<type 'long'>
  
>>> type(2-1j)
  
<type 'complex'>
  (2)数字类型函数
  Python数字类型函数主要执行两个方面的功能:

[*]  用于数字类型转换(工厂函数)
[*]  用于执行一些常用运算(内建函数)
  (a)转换工厂函数
  int(),long(),float()和complex()用于将其他数值类型转换为相应的数值类型。
  需要注意的是,在Python2.2以前,这些转换函数只是作为Python的内建函数使用,但在之后,由于Python的类和类型进行了统一,所以这些内建函数实为工厂函数(在《Python回顾与整理2:Python对象》中介绍过,即这些转换函数都是类对象,调用它们实际上是生成了该类的一个实例,这点尤其需要注意):
>>> type(int)  
<type 'type'>
  
>>> type(long)
  
<type 'type'>
  分别介绍如下:

[*]  int(obj,base=10):将其他类型数值转换为int类型数值或将数值字符串转换为int类型数值
  base为进制转换参数,如果是数字类型之间的转换,则不需要提供这个参数,否则会引发异常:
>>> int(3.0)  
3
  如果是对字符串进行转换,则可以提供进制参数,表示要转换的字符串原来的进制,默认base为10:
>>> int('123')  
123
  
>>> int('123', 8)
  
83
  
>>> int('123', 16)
  
291
  当然也可以指定为0,说明把原来的字符串数作为一个整型(跟base=10时一样):
>>> int('123', 0)  
123

[*]  long(obj,base=10):将其他类型数值转换为long类型数值或将数值字符串转换为long类型数值,与int()的使用方法一样
[*]  float(obj):将其他类型数值转换为float类型数值或将数值字符串转换为float类型数值
>>> float(123)  
123.0
  
>>> float('123')
  
123.0

[*]  complex(str)或complex(real,imag=0.0):将complex数值字符串转换为complex类型数值
>>> complex(2.3e-10, 45.3e4)  
>>> complex('2+3j')
  
(2+3j)
  
(2.3e-10+453000j)
  (b)功能函数
  即主要用来对数值进行运算的函数,包括:abs(),
coerce, divmod(), pow()和round(),这些函数为内建函数:
>>> type(abs)  
<type 'builtin_function_or_method'>
  
>>> type(coerce)
  
<type 'builtin_function_or_method'>
  分别介绍如下:

[*]  abs(num):返回给定参数的绝对值,如果是参数为复数,则返回复数的模长
>>> abs(-1)  
1
  
>>> abs(10.0)
  
10.0
  
>>> abs(3+4j)
  
5.0

[*]  coerce(num1,num2):将num1和num2转换为同一类型,然后以一个元组的形式返回
>>> coerce(3, 3+2j)  
((3+0j), (3+2j))
  
>>> coerce(3.0, 2)
  
(3.0, 2.0)
  
>>> coerce(3, 2L)
  
(3L, 2L)
  
>>> coerce(3, 2)
  
(3, 2)

[*]  divmod(num1,num2):接收两个参数,返回一个包含商和余数的元组
>>> divmod(10, 3)  
(3, 1)
  
>>> divmod(10, 2.5)
  
(4.0, 0.0)
  
>>> divmod(2+1j, 0.5-1j)
  
((-0+0j), (2+1j))

[*]  pow(num1,num2, mod=1):取num1的num2次方,如果提供mod参数,则计算结果再对mod取余
>>> pow(2, 5)  
32
  
>>> pow(2, 5, 15)
  
2

[*]  round(flt,ndig=1):接受一个浮点型flt并对其四舍五入,保存ndig位小数,若不提供ndig参数,则默认小数点后0位
>>> round(3.499)  
3.0
  
>>> round(3.599)
  
4.0
  
>>> round(3.49999, 1)
  
3.5
  提及round(),来区分下面的三个函数:

[*]  int():直接去掉小数部分,结果为整型
[*]  math.floor():得到最接近原数但又小于原数的整型(返回值为浮点型)
[*]  round():四舍五入
  可以举下面的例子来作区分:
>>> from math import floor  
>>> def compare(num):
  
...print 'int(%.1f)\t%+.1f' % (num, int(num))
  
...print 'floor(%.1f)\t%+.1f' % (num, floor(num))
  
...print 'round(%.1f)\t%+.1f' % (num, round(num))
  
...
  
>>> compare(0.2)
  
int(0.2)+0.0
  
floor(0.2)+0.0
  
round(0.2)+0.0
  
>>> compare(0.7)
  
int(0.7)+0.0
  
floor(0.7)+0.0
  
round(0.7)+1.0
  
>>> compare(1.2)
  
int(1.2)+1.0
  
floor(1.2)+1.0
  
round(1.2)+1.0
  
>>> compare(1.7)
  
int(1.7)+1.0
  
floor(1.7)+1.0
  
round(1.7)+2.0
  
>>> compare(-0.2)
  
int(-0.2)+0.0
  
floor(-0.2)-1.0
  
round(-0.2)-0.0
  
>>> compare(-0.7)
  
int(-0.7)+0.0
  
floor(-0.7)-1.0
  
round(-0.7)-1.0
  
>>> compare(-1.2)
  
int(-1.2)-1.0
  
floor(-1.2)-2.0
  
round(-1.2)-1.0
  
>>> compare(-1.7)
  
int(-1.7)-1.0
  
floor(-1.7)-2.0
  
round(-1.7)-2.0
  这样比较之后,它们之间的区别就非常明显了。
  (3)仅用于整型的函数
  主要有两类,一类用于进制转换,另一类用于ASCII转换。需要注意的是,这里的整形包括标准整型和长整型。
  (a)进制转换函数
  主要是下面的两个函数:

[*]  oct():将数值转换为八进制数,返回值为字符串
[*]  hex():将数值转换为十六进制数,返回值为字符串
  如下:
>>> hex(255)  
'0xff'
  
>>> hex(3893)
  
'0xf35'
  
>>>
  
>>> oct(255)
  
'0377'
  
>>> oct(3893)
  
'07465'
  (b)ASCII转换函数
  主要是下面的两个函数:

[*]  chr():接受一个单字节整型值(0~255),返回一个字符串(其实是一个字符,只是在Python中并没有“字符数据类型”)
[*]  ord():接受一个ASCII范围内的字符,返回其对应的整型值
[*]  unichr():接受Unicode码值,返回其对应的Unicode字符
  如下:
>>> chr(65)  
'A'
  
>>>
  
>>> ord('A')
  
65
  
>>>
  
>>> unichr(1725)
  
u'\u06bd'
  
>>> print unichr(1725)
  7.其他数字类型
  (1)布尔“数”
  布尔类型只有两个值:True和False,实际上它是整型的子类,只是它不能再被继承而生成它的子类,其它的注意点如下:

[*]  没有__nonzero__()方法的对象的布尔值默认是True
[*]  值为零的任何数字或空集(空列表空元组和空字典等)在Python中的布尔值都是False
  下面举几个例子:
>>> bool(1)  
True
  
>>> bool(3)
  
True
  
>>> bool([])
  
False
  对于对象的__nonzero__()方法,可见下面的例子:
#对象无__nonzero__方法的情况  
>>> class C: pass
  
...
  
>>> c = C()
  
>>> bool(c)
  
True
  

  
#重载__nonzero__方法,使它返回False
  
>>> class C:
  
...def __nonzero__(self):
  
...    return False
  
...
  
>>> c = C()
  
>>> bool(c)
  
False
  
>>> bool(C)
  
True
  (2)十进制浮点数
  该问题在Python后续版本中已经解决,如下:
>>> 0.1  
0.1
  当然,如果你在安卓手机上使用QPython,会发现该问题依然存在。
  8.相关模块
  比较著名的是Numeric(NumPy)和SciPy,这两个包都是第三方扩展包。
  其它的数字类型相关模块为:decimalarraymath/cmathoperatorrandom,需要用到时,查阅相关资料即可,这里主要介绍一下random模块。
  random模块中最常用的函数如下:

[*]  randint(num1,num2):返回num1和num2之间的随机整数(能取到下限和上限)
>>> random.randint(1, 2)  
2
  
>>> random.randint(1, 2)
  
2
  
>>> random.randint(1, 2)
  
2
  
>>> random.randint(1, 2)
  
1

[*]  randrange(num1,num2):返回值为range(num1,num2)之间的数,即不能取到上限
>>> random.randrange(1, 2)  
1
  
>>> random.randrange(1, 2)
  
1
  
>>> random.randrange(1, 2)
  
1
  
……
  结果总是为1。

[*]  uniform(num1,num2):几乎和randint()一样,不过它返回的是二者之间的一个浮点型(不包括范围上限)
>>> random.uniform(1, 2)  
1.2845602051034062
  
>>> random.uniform(1, 2)
  
1.0178567905561313
  
>>> random.uniform(1, 2)
  
1.8440532614481977

[*]  random():类似于uniform,不过它不接收参数,并且下限恒等于0.0,上限恒等于1.0
>>> random.random()  
0.04360809434722357
  
>>> random.random()
  
0.7386566820354784
  
>>> random.random()
  
0.8564193451546396

[*]  choice():随机返回给定序列的一个元素
>>> random.choice('xpleaf')  
'l'
  
>>> random.choice('xpleaf')
  
'f'
  
>>> random.choice('xpleaf')
  
'f'
  
>>> random.choice()
  
1
  
>>> random.choice()
  
1
  
>>> random.choice()
  
3
  OK,数字类型的总结就到这里了,虽然实际当中你可能并不需要用到这么多的特性,不过学习过之后,你会对Python有更深入的了解。
页: [1]
查看完整版本: Python回顾与整理3:数字