Python自学指南---基础篇(五)数据类型-Number

前一节中,我们对Python中的对象有了一个基本的了解。从本节开始,我们将分别了解不同类型的对象,并且对不同对象的特点,特别是对象有关的函数进行介绍。

本节将会介绍数字类型,也就是Number类型,在Python中是一种不可变类型

5.1 整数

Python能够处理任意大小的整数,例如0,-1,9989080等等
除了用一般的十进制表示,也可以用二进制(0x)、八进制(0b)、十六进制表示(0o)。并且不同进制的转换有相应的内置函数:

print("十进制数为:", 5)
print("转换为二进制为:", bin(5))
print("转换为八进制为:", oct(5))
print("转换为十六进制为:", hex(5))

执行结果为:

十进制数为:5
转换为二进制为: 0b101     
转换为八进制为: 0o5      
转换为十六进制为: 0x5

5.2 浮点数

浮点数也就是小数,例如3.14,5.34,-0.3等等,也可以用科学计数法表示,用e来代替10,例如3.14x109 就要用3.14e9来表示。

5.3 复数

Python中复数的表示与我们在课本中学到的一致,分为实部和虚部,虚部末尾需要加j或J,例如4.2+5j43-0.9J。需要注意的是,Python中复数的实部和虚部都是浮点数

复数对象主要的两个属性就是real、imag,分别返回实部和虚部,还有一个conjugate方法,返回共轭复数

>>> num = 4.2+5j
>>> 
>>> num.real
4.2
>>> num.imag
5.0
>>> num.conjugate()
(4.2-5j)

5.4 布尔型

在Python中布尔型严格来说也是整数的一种,布尔型只有两个值,TrueFalse,主要运用在逻辑运算上。

任意一个类型的对象都可以通过bool()转换为对应的布尔值,实际程序中可能很少会用到这个函数,但是必须要牢记不同对象对应的布尔值是什么,规则如下:

  • 数字(int,float,complex)只要为0,对应布尔值就是False,反之为True
  • 空的容器对象(空的str、list、tuple、dict、set)在Python中的布尔值都是 False、非空的为True
  • 没有__nonzero__()方法的对象的默认值是True

5.5 运算符与重要的内置函数

了解了各种数字类型之后,接下来就是学习在程序中如何使用它们,这就涉及到各种不同的运算符以及内置函数。

5.5.1 算数运算符

算数运算符包括加减乘除(+,-,*,/,//),取余(%),幂运算(**)。算数运算符的使用有以下几个需要注意的要点

  1. 操作数类型不一

举个例子,在使用加法的时候,用一个整数加小数是很常见的,譬如9.8+1但理论上,Python中使用+时,左右两个操作数应当是相同类型。之所以9.8+1这个表达式依然可以正确地执行,是因为Python使用了隐式的数字类型强制转换机制来保证操作数类型一致。

强制转换的机制可以参考《Python核心编程》中的描述:

如果有一个操作数是复数, 另一个操作数被转换为复数。
否则,如果有一个操作数是浮点数, 另一个操作数被转换为浮点数。
否则, 如果有一个操作数是长整数,则另一个操作数被转换为长整数;
否则,两者必然都是普通整数,无须类型转换。

强制转换的规则很好理解,只要记住**精度低的操作数向精度较高的操作数看齐(有时会把精度更高称作“更宽的类型”)**就可以了。例如9.8+1,Python会把1隐式地转换为浮点数。

强制转换是一种隐式转换,不需要程序员的参与,当然Python也提供了一些显式的类型转换函数,分别为int(),float(),complex()

  1. true除法和floor除法

在Python2.2之前的版本中,表示除法的运算符只有/这一个,它可以进行两种类型的除法:

  • floor除法:即“地板除”,两个操作数都是整数,返回的是不大于正确结果的最大整数。有一些教程中会说截取了结果的小数部分,这种说法是恰当的,因为结果为负数的时候不符合这个规则:
#Python 2.7.13
>>> 1 / 2
0
>>> -1 / 2
-1         #结果是-1而不是0
  • true除法:只要有一个操作数是浮点数,结果返回的就是浮点数:
#Python 2.7.13
>>> 1.0 / 2
0.5
>>> 1 / 2.0
0.5
>>> 1 / float(2)
0.5

在Python2.2之后,设计者们为了使语言更加简洁明了,就将floor除法的功能剥离出来,用//来表示。这样,无论操作数是整数还是浮点数,//都将执行floor除法:

>>> 1 // 2
0
>>> 1.0 // 2
0
>>> 1 // 2.0
0

不过,只要你使用的是Python2.x,你就会发现/仍然可以表示true除法和floor除法。在Python3.x中,/才变成了仅代表true除法

#Python 3.x
>>> 1 / 2
0.5
>>> 1.0 / 2
0.5
>>> 1 / 2.0
0.5

如果你希望在Python2.x中让/只表示true除法,可以在程序中加入这样一条语句from __future__ import division

  1. 取余运算

取余只需要记住一个要点:取余过程中的一定是整数,并且是通过floor除法得到的整数。

  1. 幂运算

幂运算**需要注意优先级问题。

首先,一元操作符(+,-代表取正,取负)的优先级大于加减乘除和取余(+,-,*,/,//,%)运算,可以用一个例子来理解:

>>> -1 // 2
-1
>>> -(1 // 2)
0

这里的-表示取负数,优先级一定大于//,编写程序的时候保险起见也可以加上括号,-1 // 2其实也就等价于(-1) // 2

幂运算**比较特殊,它会比左侧操作数的一元运算符优先级高,这也就是说-1 ** 2(-1) ** 2不等价:

>>> -1 ** 2   #幂运算先计算
-1
>>> (-1) ** 2     
1

另外,除了运算符**,Python还提供了内置函数pow()用于乘方运算。

传入两个参数时,pow(x, y)等价于x**y

传入三个参数时,且x,y,z都为整数时,pow(x, y, z)x ** y % z等价,而当x,y,z有一个不是整数时,pow(x, y, z)会报错:

>>> pow(3, 6, 6.0)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: pow() 3rd argument not allowed unless all arguments are integers

此外,math模块中还提供了sqrt()函数,用于开平方,不过完全可以用pow()来代替:

from math import *   #为了使用sqrt()必须导入math模块,pow则不用
>>> sqrt(8)
2.8284271247461903
>>> pow(8,0.5)   #开平方
2.8284271247461903
>>> pow(8,1/3)   #开三次方
2.0
5.5.2 比较运算符

比较运算符包括==,!=,>,<,>=,<= ,运算返回的结果是bool值(TrueFalse),常用在条件判断中,例如if a != b:…

5.5.3 逻辑运算符

逻辑运算符包括and,or,not ,分别对应与、或、非。也常用在条件判断中,例如if a and b:…
if not b:…

注意Python中逻辑运算不会直接返回bool值(TrueFalse),实际规则如下:

逻辑表达式返回规则
x and y如果 bool(x) 为 False,x and y 返回 x,否则返回 y 。
x or y如果 bool(x) 为 True,x and y 返回 x,否则返回 y 。
not x如果 bool(x) 为 False,not x 返回 True,否则返回 False 。
5.5.4 成员运算符

成员运算符包括in,not in ,可以用于判断特定的对象是否存在于序列中中,运算返回的结果是bool值(TrueFalse

>>> 1 in [1, 2, 3]
True
>>> 'd' in "abc"
False

in一般会与for连用,用于遍历序列,例如下面这个例子:

#判断list_1的哪些字符存在于list_2中
list_1 = ['A','B','C','D']
list_2 = ['A','B']

for letter in list_1:
    if letter in list_2:
        print(letter+' is exists in list_2')
    else:
        print(letter+' is not exists in list_2')

运行结果:

A is exists in list_2
B is exists in list_2
C is not exists in list_2
D is not exists in list_2
5.5.5 身份运算符

身份运算符包括is,is not,用于判断两个变量是否引用自同一个对象,因此,a is b 也就等价于 id(a) == id(b)

5.5.6 赋值运算符

赋值运算在第二章中已经作为基本语法介绍过,主要包括的就是普通的赋值运算=,以及结合算术运算符的增量运算+=,-=,*=,/=,//=,%=,**=

5.5.7 位运算符

还有一个初学时不常用,但实际上非常实用的运算符,就是位运算符。位运算中包含运算符&,|,^,~,<<,>>

首先要记住的是,位运算的操作数都是整数,并且运算针对的是整数的二进制形式

先介绍&,|,^ 这三个运算符,它们分别被称为“按位与”、“按位或”、“按位异或”。先说&,实际上就是把左右两个操作数的二进制形式逐位进行与运算,得到一个新的二进制数,用一个例子来理解:

>>> a = 60      # 60 = 0011 1100 
>>> b = 13      # 13 = 0000 1101 
>>> a & b
12              # 12 = 0000 1100

以此类推,|、^就是将每一位上的与运算改为或运算和异或运算即可。

运算符的作用是“按位取反”,顾名思义,就是将二进制的每一位1变为0,0变为1。

<<,>>是左移运算符和右移运算符,用于将运算数的各二进位全部左移或右移若干位

>>> a = 13     # 13 = 0000 1101 
>>> a << 1     
26             # 26 = 0001 1010 
>>> a << 2
52             # 52 = 0011 0100 
>>> a >> 1
6              # 6 = 0000 0110 

除了各类运算符之外,还有一些针对数字类型对象的内置函数需要了解

5.5.8 舍入函数
  1. floor(x)
    floor代表地板,那么顾名思义,就是在传入参数的“下面”,即取不大于传入参数的最大整数:
>>> floor(1.3)
1
>>> floor(-1.3)
-2
  1. ceil(x)
    ceil代表房顶,就是在传入参数的“上面”,即取不小于传入参数的最小整数:
>>> ceil(1.3)
2
>>> ceil(-1.3)
-1
  1. round(x, [, n] ) (这里x不能缺省,代表目标操作数,而n是可以缺省的,代表保留几位小数,缺省为0)

人们有时候会说round()的作用是四舍五入:

>>> round(8.2)
8
>>> round(-9.6)
-10

round()也可以指定保留几位小数:

>>> round(8.5)
8
>>> round(56.659, 1)
56.7

不过在使用的时候,可能会发现一些问题:

在python2.x中运行:

>>> round(2.5)
3.0
>>> round(-2.5)
-3.0

在python3.x中运行:

>>> round(2.5)
2
>>> round(-2.5)
-2
>>> round(3.5)
4
>>> round(-3.5)
-4

因此准确来说,round()一方面可以完成的是四舍六入的功能;另一方面,当传入的数字与两侧整数距离相同的时候,python2.x的做法是:保留到离0较远的一侧,而python3.x的做法是:保留到偶数的一侧

需要注意的是,上述规则适用于传入的数字与两侧整数距离相同的时候,那么按理来说,无论python2.x还是python3.x,round(2.675, 2)的结果都应该是2.68,但是实际上结果却是2.67!这主要是因为2.675转换为二进制之后,小数点后面的位数太多了(大约是10.10101100110011001100110011001100110011001100……),超出了计算机能够表示的精度,因此小数点后面的一串二进制数已经被截断了一部分,因此2.675在计算机中并不能精确表示,而是离2.67更近一些,使用round()时直接舍到2.67即可。

可见,round()结果会受到计算机本身表示精度的影响,因此可能会带来一些意想不到的结果,如果对精度要求高的计算,尽量避免使用round()
,一些替代的方案可以参考这篇blog:
http://www.runoob.com/w3cnote/python-round-func-note.html

5.5.9 random模块

random模块中包含了多个生成随机数对象的函数,是Python中的一个非常常用的模块。

在使用random模块前需要导入:

import random

这里提一个代码风格上的问题。我们在之前导入math模块的时候使用的是from math import * 同样我们可以使用import math,区别在于前者我们可以直接调用模块的内置函数,例如sqrt();而后者这样导入,我们必须采用模块.函数的格式调用内置函数:math.sqrt()。Python的技术规格中更建议使用后者,这是因为不同模块中可能有同名的函数,为了避免混淆,在调用模块内置函数的时候,最好还是在函数名前面加上模块名。

回到random模块,主要的几个函数如下:

  1. random.random()

生成一个0到1之间的随机浮点数,包括0但不包括1,也就是[0.0, 1.0)

>>> random.random()
0.02025527401777727
  1. random.randint(x, y)

随机生成[x,y](包括x, y)区间内的整数,需要注意x,y都必须是整数,且x<=y

>>> random.randint(1,9)
4
  1. random.uniform(x, y)

随机生成 [x, y) 或[y,x)区间内的浮点数,注意x,y可以不是整数,并且不用考虑大小

>>> random.uniform(10.6,1.5)
9.664643121543374
  1. random.randrange ([start,] stop [,step])
    该方法返回[start, stop),并且递增基数为step的集合内的一个随机整数。start缺省值为0,step缺省值为1。注意start, stop, step都必须为整数。
>>> random.randrange(1, 100, 2)   #从1-99中选一个奇数
93
>>> random.randrange(100)   #从0-99中选一个随机整数
2
>>> random.randrange(0, 100, 5)   #以5为递增基数,从0-99中选一个随机数
45

以上四个函数用于生成随机数,下面看一个能够控制随机数生成的函数

  1. random.seed([x])
    传入该函数一个固定的seed值,就能够让随机数固定:
>>> random.seed( 10 )
>>> random.random()
0.5714025946899135
>>> random.seed( 10 )
>>> random.random()
0.5714025946899135
>>> random.seed( 10 )
>>> random.random()
0.5714025946899135

这其实也说明了random模块中的函数生成的是伪随机数,即生成随机数的算法是固定的改变的只是算法的参数seed值,如果不手动设定seed值,Python就会根据系统时间自行设定seed值。

接下来再看几个与序列有关的函数,序列将会在之后的章节中详细介绍,这里提前接触一下。Python中序列也就是三种:list(列表)、tuple(元组)、string(字符串)。

  1. random.choice(seq)

从序列中随机选取一个元素,并返回这个元素,seq应当是一个序列,

>>> random.choice([1, 3, 4, 6, 9])  #list(列表)
1
>>> random.choice('a string')   #string(字符串)
't'
>>> random.choice((1, 4, 5, 8))  #tuple(元组)
8
  1. random.sample(seq, n)

从序列中随机选取n个元素形成一个新的list,并返回这个list,注意n不能大于原序列seq的长度。

>>> random.sample([1, 3, 4, 6, 9], 3)
[1, 9, 6]
>>> random.sample('a string', 3)
['g', 'i', 'a']
>>> random.sample((1, 4, 5, 8), 3)
[8, 1, 4]

需要注意,无论是random.choice()还是random.sample(),都不会改变传入的原序列,而以下这个函数则不同。

  1. random.shuffle(seq)

该函数可以将序列seq中的元素打乱,random.shuffle()没有返回值,它是直接改变原序列seq。

>>> list_1 = [1, 3, 4, 6, 9]
>>> random.shuffle(list_1)     ##本身没有返回值
>>> list_1
[9, 1, 4, 6, 3]
>>> print(random.shuffle(list_1)) ##再次证明本身没有返回值
None

本章的内容较多,梳理一下结构:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值