每种语言都会有其内置的基本数据类型,我们在学一门语言时,首先需要掌握其基本数据类型,学习 python 也不例外。python 的基本类型类型介绍在前一篇已经做过介绍了,这篇详细介绍其中的 数值类型

  • python 变量
  • 几种数值类型:整数、浮点数、小数、分数、集合
  • 数值运算符
  • 数值工具模块

建议:在编程初期阶段完全是一个技术活,只要孰能生巧就行,所以在开始学习一门编程语言时一定要动手实践和操作。

变量

在 python 中创建一个变量很简单只需要简单的一个赋值语句就可以创建一个变量。如:

In[1]:  
v = 3

这条语句包含三个步骤:

  1. 创建一个值为 3 的新对象
  2. 创建一个变量 a (如果之前不存在)
  3. 关联变量 a 到 新对象

python 是一个动态类型语言,所以在创建变量的时候不需要指定类型,只要在使用之前创建它就行。这里有一个比较容易混淆的地方:数据的类型信息是存储在对象中,而不是在变量中 ,变量只是 系统表 中的一个实体,用于连接到对象。其实在 python 中我们可以将变量看做一个指针或引用,指向或引用到所赋值的对象内存块,而具体的数据类型、数据值等信息全部存储在对象内存块中。这样大家就能更好的理解 python 的动态数据类型。

In[2]:  
m = 3
n = m

m,n
执行结果:
In[3]:  
m = 'aaa'

m,n
执行结果:
变量用于计算实例
In[4]:  
a = 3
b = 4
In[5]:  
a+1, a-1
执行结果:
In[6]:  
b*3, b/2
执行结果:
In[7]:  
a%2, b**2
执行结果:
In[8]:  
2+4.0, 2.0**b
执行结果:
如果在使用变量之前没有创建过变量将会得到错误
In[9]:  
c*2
执行结果:
使两个变量引用到同一个可更改对象,用 is== 运算符比较两个变量的结果(is 计算是否为同一个对象;== 计算是否为相同的值)
In[10]:  
L1 = [2,3,4]
L2 = L1

L1,L2
执行结果:
In[11]:  
L1[0] = 24

L1,L2, (L1 is L2), (L1==L2)
执行结果:
现在我们创建两个内容一样的两个对象,分别用两个变量引用它们,再次使用用 is== 运算符比较两个变量的结果
In[12]:  
L3 = [2,3,4]
L4 = [2,3,4]

L3,L4, L3 is L4, L3==L4
执行结果:
注意一下代码执行结果
In[13]:  
X = 42
Y = 42

X,Y, X==Y, X is Y
执行结果:
这里我们的 python 表达式写的是创建了两个值为 42 的对象,但是 XYis 运算为什么是 True 呢?这是由于 python 会缓存和重复使用数字和字符串对象。我们可以使用 sys.getrefcount 查看一个对象被使用了多少次(以下的执行结果可能会每次不一样)。
In[14]:  
import sys

sys.getrefcount(42)
执行结果:
In[15]:  
X1 = 42
X2 = 42

sys.getrefcount(42)
执行结果:
变量数据格式化输出
In[16]:  
a = 3; b = 4
print(b/(2.0+a))
执行结果:
In[17]:  
num = 1 / 3.0
'%e' % num
执行结果:
In[18]:  
'%4.2f' % num
执行结果:
In[19]:  
'{0:4.2f}'.format(num)
执行结果:

基本数值类型

python 支持的数值类型比较多,大家不用一次性全部弄懂,只需要掌握集中基本的就行,剩下的在需要的时候在学习就可以了。

实例 类型
1234,-24,0,99999999 整数(不限大小)
1.23,1.0,3.14e-10,4E210,4.0e+210 浮点数
0o177, 0x9ff, 0b101010 八进制(Octal), 十六进制(hex), 二进制(binary)
3+4j, 3.0+4.0j, 3J 复数
set(‘spam’), {1,2,3,4} 集合
Decimal(‘1.0’), Fraction(1,3) 扩展类型:小数、分数
bool(x), True, False Boolean 和 常亮

运算符

python 中有很运算符供我们使用,这里简答的做下分类介绍

算数运算符

运算符 描述 实例
+ 加 - 两个对象相加 10+20 输出结果 30
- 减 - 得到负数或是一个数减去另一个数 10 - 20 输出结果 -10
* 乘 - 两个数相乘或是返回一个被重复若干次的字符串 10 * 20 输出结果 200
/ 除 - x除以y 20 / 10 输出结果 2
% 取模 - 返回除法的余数 10 % 20 输出结果 0
** 幂 - 返回x的y次幂 10**20 为10的20次方, 输出结果 100000000000000000000
// 取整除 - 返回商的整数部分 9//2 输出结果 4 , 9.0//2.0 输出结果 4.0

使用举例:

In[20]:  
40 + 3.1
执行结果:
In[21]:  
1+2*3
执行结果:
In[22]:  
2*3**2
执行结果:
In[23]:  
3**9
执行结果:
In[24]:  
10 / 4 
执行结果:
In[25]:  
10/4.0
执行结果:
In[26]:  
# 计算的数据类型
10//3, 10//3.0, 10%3, 10%3.0
执行结果:

比较云算法

运算符 描述 实例
== 等于 - 比较对象是否相等 (10 == 20) 返回 False。
!= 不等于 - 比较两个对象是否不相等 (10 != 20) 返回 true.
<> 不等于 - 比较两个对象是否不相等 (10 <> 20) 返回 true。这个运算符类似 != 。
> 大于 - 返回x是否大于y (10 > 20) 返回 False。
< 小于 - 返回x是否小于y。 (10 < 20) 返回 true。
>= 大于等于 - 返回x是否大于等于y。 (10 >= 20) 返回 False。
<= 小于等于 - 返回x是否小于等于y。 (10 <= 20) 返回 true。

所有比较运算符返回1表示真,返回0表示假。这分别与特殊的变量True和False等价。

In[27]:  
1<2
执行结果:
In[28]:  
2.0>=1
执行结果:
In[29]:  
2.0==2.0
执行结果:
In[30]:  
2.0!=2.0
执行结果:

链式写法

In[31]:  
x = 2
y = 4
z = 6
In[32]:  
x<y<z, x<y and y<z
执行结果:
In[33]:  
x<y>z, x<y and y>z
执行结果:
In[34]:  
1==2<3  # same as: 1==2 and 2<3
执行结果:
在浮点数比较时,注意精度问题
In[35]:  
1.1+2.2 == 3.3
执行结果:
In[36]:  
1.1+2.2
执行结果:
In[37]:  
int(1.1+2.2) == int(3.3)
执行结果:

赋值运算符

运算符 描述 实例
= 简单的赋值运算符 c = a + b 将 a + b 的运算结果赋值为 c
+= 加法赋值运算符 c += a 等效于 c = c + a
-= 减法赋值运算符 c -= a 等效于 c = c - a
*= 乘法赋值运算符 c *= a 等效于 c = c * a
/= 除法赋值运算符 c /= a 等效于 c = c / a
%= 取模赋值运算符 c %= a 等效于 c = c % a
**= 幂赋值运算符 c **= a 等效于 c = c ** a
//= 取整除赋值运算符 c //= a 等效于 c = c // a

复制运算符左边必须是变量

In[38]:  
a = 10
b = 20
In[39]:  
c = a +b
c
执行结果:
In[40]:  
c += 3
c
执行结果:
如果复制运算符左边不是变量将会发生错误
In[41]:  
1 = a+b
执行结果:

位运算符

运算符 描述 实例
& 按位与运算符:参与运算的两个值,如果两个相应位都为1,则该位的结果为1,否则为0 (a & b) 输出结果 12 ,二进制解释: 0000 1100
| 按位或运算符:只要对应的二个二进位有一个为1时,结果位就为1。 (a | b) 输出结果 61 ,二进制解释: 0011 1101
^ 按位异或运算符:当两对应的二进位相异时,结果为1 (a ^ b) 输出结果 49 ,二进制解释: 0011 0001
~ 按位取反运算符:对数据的每个二进制位取反,即把1变为0,把0变为1 。~x 类似于 -x-1 (~a ) 输出结果 -61 ,二进制解释: 1100 0011,在一个有符号二进制数的补码形式。
<< 左移动运算符:运算数的各二进位全部左移若干位,由 << 右边的数字指定了移动的位数,高位丢弃,低位补0。 a << 2 输出结果 240 ,二进制解释: 1111 0000
>> 右移动运算符:把”>>“左边的运算数的各二进位全部右移若干位,>> 右边的数字指定了移动的位数 a >> 2 输出结果 15 ,二进制解释: 0000 1111
In[42]:  
x = 1
x<<2
执行结果:
In[43]:  
x|2
执行结果:
In[44]:  
x & 1
执行结果:
In[45]:  
X = 0b0001
In[46]:  
X<<2
执行结果:
In[47]:  
bin(X<<2)
执行结果:
In[48]:  
bin(X|0b010)
执行结果:
In[49]:  
bin(X & 0b1)
执行结果:
In[50]:  
X = 0xFF
bin(X)
执行结果:
In[51]:  
bin(X ^ 0b10101010)
执行结果:

逻辑运算符

运算符 逻辑表达式 描述 实例
and x and y 布尔”与” - 如果 x 为 False,x and y 返回 False,否则它返回 y 的计算值。 (10 and 20) 返回 20。
or x or y 布尔”或” - 如果 x 是非 0,它返回 x 的值,否则它返回 y 的计算值。 (10 or 20) 返回 10。
not not x 布尔”非” - 如果 x 为 True,返回 False 。如果 x 为 False,它返回 True。 not(10 and b20) 返回 False

逻辑运算符的结果是真或假,首先看看 python 中如何表示真和假

python 提供了 bool 类型来表示真假,且这个类型只有两个常亮值:True 和 False

In[52]:  
type(True), type(False)
执行结果:
In[53]:  
isinstance(True, int)
执行结果:

True 和 False 在 python 内部使用整数 1 和 0 表示,也就是说它们的值和整数 1、0 相等。但是他们和整数 1、0 是不同的对象

In[54]:  
True == 1, False==0
执行结果:
In[55]:  
True is 1, False is 0
执行结果:

由于 True 和 False 的值等于 1 和 0 ,所以他们可以参与部分数值计算。但是强烈建议不要这样使用

In[56]:  
True + 4, False / 4
执行结果:
逻辑计算实例:
In[57]:  
(10 and 20), not(10 and 20)
执行结果:
In[58]:  
True and False, True or False
执行结果:

成员运算符

运算符 描述 实例
in 如果在指定的序列中找到值返回 True,否则返回 False。 x 在 y 序列中 , 如果 x 在 y 序列中返回 True。
not in 如果在指定的序列中没有找到值返回 True,否则返回 False。 x 不在 y 序列中 , 如果 x 不在 y 序列中返回 True。
In[59]:  
'a' in 'abb', 'a' in 'bbb'
执行结果:
In[60]:  
1 in [1,2,2,3], 0 not in [1,2,2,3]
执行结果:

身份运算符

运算符 描述 实例
is is 是判断两个标识符是不是引用自一个对象 x is y, 类似 id(x) == id(y) , 如果引用的是同一个对象则返回 True,否则返回 False
is not is not 是判断两个标识符是不是引用自不同对象 x is not y , 类似 id(a) != id(b)。如果引用的不是同一个对象则返回结果 True,否则返回 False。
In[61]:  
'a' is 'a'
执行结果:
In[62]:  
[1,1] is [1,1], [12] is not [1,1]
执行结果:

优先级

当在表达式里面同时使用多个运算符时,需要注意各个运算符的优先级,优先级高的将被优先执行。以下表格列出了从最高到最低优先级的所有运算符:

运算符 描述
** 指数 (最高优先级)
~ + - 按位翻转, 一元加号和减号 (最后两个的方法名为 +@ 和 -@)
* / % // 乘,除,取模和取整除
+ - 加法减法
>> << 右移,左移运算符
& 位 ‘AND’
^ | 位运算符
<= < > >= 比较运算符
<> == != 等于运算符
= %= /= //= -= += *= **= 赋值运算符
is is not 身份运算符
in not in 成员运算符
not or and 逻辑运算符

**当需要改变表达式执行顺序的时候,可以使用 () **

In[63]:  
(1+2)*3, 1+2*3
执行结果:
In[64]:  
(2*3)**2, 2*3**2
执行结果:

数值类型转换

In[65]:  
int(3.1415)
执行结果:
In[66]:  
float(3)
执行结果:

进制转换

python 可以支持任意进制的数值,常用的有二进制、八进制、十进制、十六进制,进制之间可以任意转换。

In[67]:  
0o1, 0o20, 0o377 # 8进制
执行结果:
In[68]:  
0x01, 0x10, 0xFF # 16进制
执行结果:
In[69]:  
0b1, 0b10000, 0b11111111 # 2进制
执行结果:
In[70]:  
64, 0o100, 0x40, 0b1000000
执行结果:
In[71]:  
# 十进制转换到 8、16、2 进制
oct(64), hex(64), bin(64) 
执行结果:
In[72]:  
# 二进制转十进制
int('01010101', 2)
执行结果:
In[73]:  
# 获取数值的二进制位数
X = 99
bin(X), X.bit_length(), len(bin(X))-2
执行结果:
In[74]:  
# 不同进制的字符串表示转换成数字
int('64'), int('100', 8), int('40',16), int('1000000', 2)
执行结果:
In[75]:  
eval('64'), eval('0o100'), eval('0x40'), eval('0b1000000')
执行结果:
In[76]:  
# 数值不同进制输出
'{0:o}, {1:x}, {2:b}'.format(64, 64, 64)
执行结果:
In[77]:  
'%o, %x, %x, %X' % (64,64,255,255)
执行结果:

其他数值类型

复数

In[79]:  
1j * 1j
执行结果:
In[80]:  
2+1j*3
执行结果:
In[81]:  
(2+1j) * 3
执行结果:

小数

由于浮点数的精度问题,在计算时没有办法绝对精确,这个时候就需要使用的小数类型。比如如下计算,我们都知道最后结果为 0,但是 python 的执行结果却不是 0

In[82]:  
0.1+0.1+0.1 - 0.3
执行结果:
In[83]:  
# python 中使用小数需要用到 decimal 模块
from decimal import Decimal

Decimal('0.1') + Decimal('0.1') + Decimal('0.1') - Decimal('0.3')
执行结果:
In[84]:  
Decimal('0.1') + Decimal('0.10') + Decimal('0.10') - Decimal('0.30')
执行结果:
对于传入 Decimal 是一个浮点数时,结果和我们预期会有些出入,大家使用的时候注意
In[85]:  
Decimal(0.1) + Decimal(0.1) + Decimal(0.1) - Decimal(0.3)
执行结果:
对于一些无限小数,可以使用 decimal.getcontext().prec 指定精度(就是小数位数)
In[86]:  
import decimal
decimal.Decimal('1') / decimal.Decimal('7')
执行结果:
In[87]:  
decimal.getcontext().prec = 4
decimal.Decimal(1) / decimal.Decimal(7)
执行结果:
在处理进度的时候,可以结合 python 的 with 语句进行上下文管理,关于上下文的概念后面会详细讲解
In[88]:  
# 设置全局上下文精度
decimal.getcontext().prec = 4
print(decimal.Decimal('1.00') / decimal.Decimal('3.00'))


with decimal.localcontext() as ctx:
    # 设置局部上下文精度,覆盖全局上下文精度
    ctx.prec = 2
    decimal.Decimal('1.00') / decimal.Decimal('3.00')
    print(decimal.Decimal('1.00') / decimal.Decimal('3.00'))
    
# 当退出 with 语句的时候,局部上下文精度失效,返回全局上下文精度
print(decimal.Decimal('1.00') / decimal.Decimal('3.00'))
decimal.Decimal('1.00') / decimal.Decimal('3.00')
执行结果:

Fraction (分数)

在上面使用小数的时候,当遇到无限小数的时候,即使使用 Decimal 还是不能完全精确表示一个数,这个时候 python 为我们提供了分数类型

In[89]:  
from fractions import Fraction

x = Fraction(1,3)
y = Fraction(4,6)
In[90]:  
x
执行结果:
In[91]:  
y
执行结果:
In[92]:  
print(y)
执行结果:
In[93]:  
x+y
执行结果:
In[94]:  
x-y
执行结果:
In[95]:  
x*y
执行结果:
In[96]:  
Fraction('.25')
执行结果:
In[97]:  
Fraction(0.25)
执行结果:
In[98]:  
Fraction('1.25')
执行结果:
In[99]:  
Fraction('.25') + Fraction('1.25')
执行结果:

fractions 和 decimals 中的数值计算

In[100]:  
0.1+0.1+0.1 - 0.3
执行结果:
In[101]:  
Fraction('0.1') + Fraction('0.1') + Fraction('0.1') - Fraction('0.3')
执行结果:
In[102]:  
Fraction(1,10) + Fraction(1,10) + Fraction(1,10) - Fraction(3,10)
执行结果:
In[103]:  
Decimal('0.1') + Decimal('0.10') + Decimal('0.10') - Decimal('0.30')
执行结果:

Frcation 转换

In[104]:  
# 浮点数 => 分数

from fractions import Fraction

print((2.5).as_integer_ratio())
f=2.5
z = Fraction(*f.as_integer_ratio()) # 构造函数
print(z)

print(Fraction.from_float(1.75)) # from_float 静态方法
执行结果:
In[105]:  
x = Fraction(1, 3)
x, x+z
执行结果:
In[106]:  
float(x), float(x+z)
执行结果:
In[107]:  
x = Fraction(1, 3)

x
执行结果:
In[108]:  
print(x + 2)   # Fraction + int -> Fraction
执行结果:
In[109]:  
x + 2.0   # Fraction + float -> float
执行结果:
In[110]:  
x + Fraction(3,4) # Fraction + Fraction -> Fraction
执行结果:

限制最大分母值

In[111]:  
Fraction('0.1')
执行结果:
In[112]:  
Fraction(*(0.1).as_integer_ratio())
执行结果:
In[113]:  
Fraction.from_float(0.1).limit_denominator(10)
执行结果:

集合

这里说的集合和其他语言里面的集合数据类型有所不同,更像是数学里面集合的概念,可以做一些集合运算。只是集合里面不能含有重复的值。

In[114]:  
x = set([1,2,3])
y = set([3,4,5])
In[115]:  
x==y
执行结果:
In[116]:  
x>y
执行结果:
In[117]:  
x<y
执行结果:
In[118]:  
x-y
执行结果:
In[119]:  
x|y
执行结果:
In[120]:  
x&y
执行结果:
In[121]:  
x ^ y
执行结果:
In[122]:  
1 in x, 0 in x
执行结果:
In[123]:  
z = x.intersection(y)
z
执行结果:
集合 和 list 是不同饿数据类型,尽管开起来相似,使用起来也相似,但是请他们确实是不同的数据类型,所以集合不能和 list 进行运算
In[124]:  
x | [6,7]
执行结果:
In[125]:  
x | {6,7}
执行结果:
In[126]:  
type({1,2}), type({})
执行结果:

集合方法

In[127]:  
x.union({6,7})
执行结果:
In[128]:  
x.union([6,7])
执行结果:
In[129]:  
x.union(set([6,7]))
执行结果:
In[130]:  
x.union((6,7))
执行结果:
In[131]:  
x.intersection((3,6,7))
执行结果:
In[132]:  
x.issubset(range(0,10))
执行结果:
In[133]:  
x
执行结果:
In[134]:  
x.add([3,4,5])  # 只能加入不可变对象
执行结果:
In[135]:  
x.add({'a':1})
执行结果:
In[136]:  
x.add((3,45))
x
执行结果:
In[137]:  
x | {(4,5,6),(10,3)}
执行结果:
In[138]:  
x
执行结果:
In[139]:  
(3, 45) in x
执行结果:
In[140]:  
(4,5,6) in x
执行结果:

数值工具

python 已经内置了常用的数值工具模块 math,包括 PI 常数、E 常数、正选、小数的四舍五入等工具。 由于篇幅原因这里只举例部分使用方式,并不是说其他不重要,在大家使用到的使用使用 dir()help() 查看帮助文档就行。

In[141]:  
# 引入 math 模块
import math

# pi 和 e 常数
math.pi, math.e
执行结果:
In[142]:  
math.floor(2.5), math.floor(-2.5) # 向下取整
执行结果:
In[143]:  
math.ceil(2.567), math.ceil(-2.567) # 向上整数部分
执行结果:
In[144]:  
round(2.567), round(2.467), round(2.567, 2)  # 四舍五入
执行结果:
In[145]:  
(1/3.0), round(1/3.0,3), ('%.2f'%(1/3.0))
执行结果:
In[146]:  
math.trunc(2.5), math.trunc(-2.5) # 保留整数部分
执行结果:
In[147]:  
# sin 函数
math.sin(2*math.pi/180)
执行结果:
In[148]:  
# 开平法
math.sqrt(144), 144**0.5, pow(144, 0.5), math.sqrt(2)
执行结果:
In[149]:  
# 幂操作 和 幂函数
pow(2,4), 2**4, 2.0**4.0
执行结果:
In[150]:  
# 绝对值 和 求和
abs(-42.0), sum((1,2,3,4))
执行结果:
In[151]:  
# 最小值 和 最大值
min(3,1,2,4), max(3,1,2,4)
执行结果:
In[152]:  
 dir(math)  # 查看更多的 math 方法,使用 help 函数查看使用文档。例如: help(math.acos)
执行结果:
In[153]:  
help(math.acos)
执行结果:

随机数

在写程序中往往会遇到生成随机数,或在一批数据中随机抽取一个数据的需求。这个时候就需要用到 python 内置的随机数模块 random ,这里展示几个常用的方法和方式,需要详细了解模块的使用请使用 dir()help() 查看使用文档。

In[154]:  
import random

random.random()
执行结果:
In[155]:  
random.random()
执行结果:
In[156]:  
random.randint(1,10), random.randint(1,10)
执行结果:
In[157]:  
random.choice(['a', 1, 'c', 'd'])
执行结果:
In[158]:  
random.choice(['a', 1, 'c', 'd'])
执行结果:
In[159]:  
l = ['a','b','c','d']
random.shuffle(l)
l
执行结果:
In[160]:  
random.shuffle(l)
l
执行结果:
如果想要学习更多的数值计算方法和类型,大家可以学习一下 NumPy 库。

试一试