首页 > Python资料 博客日记
【Python学习笔记】 第5章 数值类型
2024-09-09 10:00:03Python资料围观41次
数值类型基础知识
在Python中,数值实际上是一种类型的分类,包括:
-
整数、浮点数
-
复数
-
小数:固定精度对象
-
分数:有理数对象
-
集合:带有数值运算的集合体
-
布尔值:
True
,False
-
内置函数与块:
round
,math
,random
等 -
表达式、无限制精度整数(很大的整数)、位运算、八进制、十二进制、二进制
-
第三方扩展:向量、库、可视化、作图等
其中整数、浮点数最为常见,因此先从它们讲起。
数值字面量
字面量 | 解释 |
---|---|
1234, -24, 0, 99999999999999 |
整数(无大小限制) |
1.23, 1., 3.14e-10, 4E210, 4.0e+210 |
浮点数 |
0o177, 0x9ff, 0b101010 |
Python 3.X中八进制、十六进制、二进制字面量 |
0177, 0o177, 0x9ff, 0b101010 |
Python 2.X中两种八进制、十六进制、二进制字面量 |
3+4j, 3.0+4.0j, 3J |
复数字面量 |
set('spam'), {1, 2, 3, 4} |
集合 |
Decimal('1.0'), Fraction(1, 3) |
小数、分数扩展 |
bool(X), True, False |
布尔类型、字面量 |
注意:
-
浮点数带小数点,或加上科学技术标志
e/E
。如果字面量带有上述描述,那么将其识别为浮点数。 -
整数:在Python2中有32位整数和长整数(无限制长),Python3中只有整数,即无限长的整数。
-
十六进制、八进制和二进制字面量:八进制以
0o
或0O
开头,十六进制以0x
开头,二进制以0b
或0B
开头。 -
复数:字面量位实部+虚部,虚部以
j
或J
结尾。
内置数值工具
处理数字的工具包括:
-
表达式运算符
-
内置数学函数
-
工具模块
它们也有一些专用于特定类型的方法。
Python表达式运算符
表达式的定义:数字/变量与运算符相结合,在执行时计算为一个值。
Python所有的运算符表达式如下:
运算符 | 描述 |
---|---|
yield x |
生成器函数send 协议 |
lambda args: expression |
创造匿名函数(lambda表达式) |
x if y else z |
三元选择表达式,如果y 为真则取x ,否则取z |
x or y |
逻辑或 |
x and y |
逻辑与 |
not x |
逻辑非 |
x in y , x not in y |
x 是/不是y 的成员 |
x is y , x is not y |
`对象是否同一(不止是值相等) |
x < y , x > y , x <= y , x >= y |
x 是否小于/大于/不大于/不小于y |
x == y , x != y |
x 等于/不等于y (和上面的is 不一样) |
x | y |
如果是数字,则按位与;如果是集合,则取并集 |
x ^ y |
如果是数字,则按位异或;如果是集合,则取对称差集 |
x & y |
如果是数字,则按位与;如果是集合,则取交集 |
x << y , x >> y |
将x 左移/右移y 位 |
x + y |
如果是数字,则加;如果是序列,则拼接 |
x - y |
如果是数字,则减;如果是集合,则取差集 |
x * y |
如果是数字,则乘;如果是序列,则重复 |
x % y |
如果是数字,则取x 除以y 的余数;否则是格式化 |
x / y , x // y |
除法、除法向下取整 |
-x , +x |
取负、取正 |
~x |
按位非(取反码) |
x ** y |
x 的y 次幂 |
x[i] |
索引 |
x[i:j:k] |
分片 |
x(...) |
调用函数/方法/类等等 |
x.attr |
属性引用 |
(...) |
元组、表达式、生成器表达式 |
[...] |
列表、列表推导 |
{...} |
字典、集合、字典与集合推导 |
混合运算遵循运算符优先级
-
以上表为标准,运算符从上到下优先级逐渐升高;
-
如果优先级相同,则从左到右运算。
括号分组子表达式
如果我们使用了括号,就不用考虑优先级,因为Python优先计算括号内的子表达式,再计算整个表达式。
混合类型向上转换
如果表达式中有复数,那么结果就为复数;如果表达式中只有整数和浮点数,则结果为浮点数;如果表达式中只有整数,则结果为整数(除非有除法)。
我们也可以通过强制转换的方法选择想要的类型:
>>> int(3.1415)
3
>>> float(3)
3.0
预习:运算符重载和多态
我们在之前也看见,+
也适用于字符串拼接。这是因为,字符串类型对+
进行了重载。用户定义的新类型也可以重载+
。
Python的这个特性叫多态。
数字的实际应用
变量与基础表达式
变量是名称,用于记录程序中的信息。在Python中:
-
变量在第一次赋值时被创建
-
变量在表达式中被使用时,会被替换为它们的值
-
变量在表达式中使用之前,必须已经赋值
-
变量引用对象,不需要事先声明
例:下面的例子中,自动创建变量a
和b
:
>>> a = 3
>>> b = 4
在表达式中使用刚刚创建的变量,此时变量替换为它们的值:
>>> a + 1, a - 1
(4, 2)
>>> b * 3, b / 2
(12, 2.0)
>>> a % 2, b ** 2
(1, 16)
>>> 2 + 4.0, 2.0 ** b
(6.0, 16.0)
注意到,我们输入了多个表达式并用逗号分隔它们,这样Python对每个表达式分别求值,并将它们用元组的方式组合起来。
如果使用还没创建的变量,则Python会报错:
>>> c * 2
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'c' is not defined
Python解释数值表达式的时候,计算的先后顺序与数学上的优先顺序一致(如先乘除后加减,如果有括号先算括号)
数值的显示格式
在早一些版本,会出现:
>>> b / (2.0 + a)
0.80000000000000004
>>> print(b / (2.0 + a))
0.8
后面的版本已经解决了这个问题。我们也可以用其他方法显示计算机中数字的位数(比如直接在交互界面输入变量名,或者使用字符串格式化):
>>> num = 1 / 3.0
>>> '%e' % num
'3.333333e-01'
>>> '%4.2f' % num
'0.33'
>>> '{0:4.2f}'.format(num)
'0.33'
普通比较与链式比较
普通数值可以进行比较,并返回一个布尔值。
>>> 2.0 >= 1
True
>>> 2.0 != 2.0
False
但是,一次比较只能比较两个数,因此Python运行我们把多个比较连接起来:
>>> X = 2
>>> Y = 4
>>> Z = 6
>>> X < Y < Z
True
>>> X < Y and Y < Z
True
实际上,前者更有效率,因为Python只计算一次Y。
比较链可以是任意形式,也可以是任意长度。
>>> X < Y > Z
False
>>> 1 < 2 < 3.0 < 4
True
如果需要判断表达式是否相等,且用到浮点数,那么对其额外处理(如判断两者的差的绝对值是否小于一个很小的数):
>>> 0.1 + 0.2 == 0.3
False
>>> 0.1 + 0.2
0.30000000000000004
除法、经典除法、向下取整除法和真除法
-
x / y
:在Python2.X中,整数取省去小数部分,浮点数保留余项;在Python3.X中,无论用何种类型,都会变成真除法(即保留小数部分)。 -
x // y
:向下取整除法。
>>> 10 / 4
2.5
>>> 10 / 4.0
2.5
>>> 10 // 4
2
>>> 10 // 4.0
2.0
可见,//
依赖于操作数的类型。
支持两个Python脚本
在Python 2.X中,要实现像Python 3.X的除法效果,需要从模块__future__
导入division
。
向下取整除法 vs 截断除法
除法//
是向下截断除法。对浮点数采用向下截断的函数是math.floor
,向零截断的函数是math.trunc
,效果如下:
>>> import math
>>> math.floor(2.5)
2
>>> math.floor(-2.5)
-3
>>> math.trunc(2.5)
2
>>> math.trunc(-2.5)
-2
在Python中,截断除法//
总是向下取整。
>>> 5 / 2, 5 / -2
(2.5, -2.5)
>>> 5 // 2, 5 // -2
(2, -3)
>>> 5 / 2.0, 5 / -2.0
(2.5, -2.5)
>>> 5 // 2.0, 5 // -2.0
(2.0, -3.0)
为什么截断很重要
Python 3.X中的非截断行为会严重影响大量的Python 2.X程序。
整数精度
Python 3.X支持无限制的整数大小,但Python 2.X识别长整数时在末尾加一个L。这方便了高精度运算(在C/C++需要额外实现)。
复数
复数的后缀为j
或J
,我们可以把实部非0的复数写成实部与虚部相加的形式。比如,实部为2,虚部为-3的复数可以写为2 + -3j
或2 - 3j
。
复数运算的例子:
>>> 1j * 1J
(-1+0j)
>>> 2 + 1j * 3
(2+3j)
>>> (2 + 1j) * 3
(6+3j)
复数允许访问实部和虚部,并支持所有数学表达式和cmath
模块中的数学函数。
十六进制、八进制和二进制:字面量与转换
在Python中,编写以0o
或0O
为开头的字面量,则将其识别为八进制;以0x
或0X
为开头的字面量,则将其识别为十六进制;以0b
或0B
为开头的字面量,则将其识别为二进制。
>>> 0o1, 0o20, 0o377
(1, 16, 255)
>>> 0x01, 0X10, 0xFF
(1, 16, 255)
>>> 0b1, 0B10000, 0b11111111
(1, 16, 255)
Python默认用十进制显示数值。如果要将一个数转换为八进制、十六进制和二进制,可以分别用oct
、hex
、bin
。
>>> oct(64), hex(64), bin(64)
('0o100', '0x40', '0b1000000')
内置函数int
将一个(十进制、八进制、十六进制、二进制)数字字符串转换为一个整数,第一个参数是要转换的字符,第二个参数是要把这个数字字符串看作是几进制,不填则默认为十进制。
>>> int('64'), int('100', 8), int('40', 16), int('1000000', 2)
(64, 64, 64, 64)
>>> int('0x40', 16), int('0b1000000', 2)
(64, 64)
eval
函数把字符串作为Python代码运行。
字符串格式化方法和表达式把整数转换为指定的字符串:
>>> '{0:o}, {1:x}, {2:b}'.format(64, 64, 64)
'100, 40, 1000000'
>>> '%o, %x, %x, %X' % (64, 64, 255, 255)
'100, 40, ff, FF'
注意,在Python3.X中用0开头的数字表示八进制会引发错误。其次,八进制、十六进制和二进制都可以是任意长度的整数。
>>> X = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
>>> X
25711008708143844408671393477458601640355247900524685364822015
>>> oct(X)
'0o77777777777777777777777777777777777777777777777777777777777777777777'
>>> bin(X)
'0b111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111'
按位操作
Python支持C语言中的大多数数学表达式,比如把整数作为二进制串处理的运算(位运算)。如:左移、右移、逻辑与/非/或/异或。
>>> x = 1 # 0001
>>> x << 2 # 0100
4
>>> x | 2 # 0001 | 0010 = 0011
3
>>> x & 1 # 0001 & 0001 = 0001
1
在位运算下,之前介绍的二进制、十六进制就十分有用(因为十六进制的每一位对应二进制的四位)。
Python引入了新的整数方法bit_length
,查询二进制表示一个数字的值时至少需要的位数。
>>> X = 99
>>> bin(X), X.bit_length(), len(bin(X)) - 2
('0b1100011', 7, 7)
事实上,位运算在Python中不太重要。
其他内置数学工具
内置模块math
:
>>> import math
>>> math.pi, math.e # 数学常数
(3.141592653589793, 2.718281828459045)
>>> math.sin(2 * math.pi / 180) # 三角函数
0.03489949670250097
>>> math.sqrt(144), math.sqrt(2) # 算术平方根
(12.0, 1.4142135623730951)
>>> pow(2, 4), 2 ** 4, 2.0 ** 4.0 # 幂运算
(16, 16, 16.0)
>>> abs(-42.0), sum((1, 2, 3, 4)) # 绝对值、和
(42.0, 10)
>>> min(3, 1, 2, 4), max(3, 1, 2, 4) # 序列的最小值、最大值
(1, 4)
模块math
包含多种取整方式:
>>> math.floor(2.567), math.floor(-2.567) # 向下取整
(2, -3)
>>> math.trunc(2.567), math.trunc(-2.567) # 向零取整
(2, -2)
>>> int(2.567), int(-2.567)
(2, -2)
>>> round(2.567), round(2.467), round(2.567, 2) # 四舍五入
(3, 2, 2.57)
注意到,优先函数如sin
需要导入math
,有些则不用。因为这些函数是内置函数,位于隐秘的命名空间内,对应于Python的builtins
模块。
随机数random
也需要导入。它可以选择在区间\([0, 1]\)的任意实数:
>>> import random
>>> random.random()
0.83057242993689
>>> random.random()
0.36589352300294087
>>> random.random()
0.9102553345613595
也可以在规定的范围内选择一个随机整数:
>>> random.randint(1, 10)
3
>>> random.randint(1, 10)
9
>>> random.randint(1, 10)
8
还能够从一个序列中随机地选取一项,以及打乱元素:
>>> random.choice(['Life of Brian', 'Holy Grail', 'Meaning of Life'])
'Holy Grail'
>>> random.choice(['Life of Brian', 'Holy Grail', 'Meaning of Life'])
'Meaning of Life'
>>>
>>> suits = ['hearts', 'clubs', 'diamonds', 'spades']
>>> random.shuffle(suits)
>>> suits
['clubs', 'diamonds', 'spades', 'hearts']
>>> random.shuffle(suits)
>>> suits
['spades', 'clubs', 'hearts', 'diamonds']
其他数值类型
小数类型
小数对象的名称是Decimal
,它们有固定的位数和小数点,它的精度是固定的。
基础知识
用浮点数来进行运算容易丢失精度:
>>> 0.1 + 0.2
0.30000000000000004
使用了小数对象,则结果更精确:
>>> from decimal import Decimal
>>> Decimal('0.1') + Decimal('0.2')
Decimal('0.3')
我们用decimal
模块中的Decimal
函数创建小数对象,传入一个表示小数的字符串。当不同精度的小数组合,则按照精确度最高的小数给出结果:
>>> Decimal('0.1') + Decimal('0.10')
Decimal('0.20')
我们可以从一个浮点数创建小数对象,但它会产生默认庞大的小数位数。
>>> Decimal(0.1) + Decimal(0.2)
Decimal('0.3000000000000000166533453694')
设置全局小数精度
默认的小数精度是:小数部分保留28位有效数字。
>>> import decimal
>>> decimal.Decimal(1) / decimal.Decimal(7)
Decimal('0.1428571428571428571428571429')
我们可以这么修改显示小数部分有效数字的位数:
>>> decimal.getcontext().prec = 4
>>> decimal.Decimal(1) / decimal.Decimal(7)
Decimal('0.1429')
>>> decimal.Decimal(0.1) + decimal.Decimal(0.2) - decimal.Decimal(0.3)
Decimal('1.110E-17')
小数上下文管理器
我们可以把特定的精度要求放在一个环境里,在环境外还是默认精度:
>>> 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')
分数类型
分数基础知识
向上面的Decimal
,分数也需要导入模块fraction
,并通过两个整数(第一个是分子,第二个是分母)作为参数构造:
>>> 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(6, 12)
Fraction(1, 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)
>>> float(x)
0.3333333333333333
>>> float(z)
2.5
注意到,float()
可以将分数类型转换为浮点数。Fraction
也有一种方法将浮点数转换为分数。
>>> Fraction.from_float(1.75)
Fraction(7, 4)
分数加整数的结果是分数,分数加浮点数的结果是浮点数:
>>> x = Fraction(1, 3)
>>> x + 1
Fraction(4, 3)
>>> x + 1.0
1.3333333333333333
但是,如果浮点数不能精确地表达某些实数(如1/3),那么转换为分数结果不精确。
>>> 1.0 / 3
0.3333333333333333
>>> (1.0 / 3).as_integer_ratio()
(6004799503160661, 18014398509481984)
我们可以限制分母地最大值来简化结果:
>>> a = Fraction(*(1.0 / 3).as_integer_ratio())
>>> a
Fraction(6004799503160661, 18014398509481984)
>>> a.limit_denominator(10)
Fraction(1, 3)
集合
集合的性质与数学中集合的性质一致。如:无序、没有重复元素。
集合基础知识
我们可以用一个序列或可迭代对象来创建集合:
>>> x = set('abcde')
>>> y = set('bdxyz')
>>> x
{'d', 'a', 'c', 'b', 'e'}
集合的运算:
>>> x - y # 差集
{'a', 'c', 'e'}
>>> x | y # 并集
{'d', 'x', 'z', 'a', 'c', 'b', 'e', 'y'}
>>> x & y # 交集
{'d', 'b'}
>>> x ^ y # 对称差
{'e', 'z', 'a', 'x', 'y', 'c'}
>>> x > y, x < y # 是否为子集
(False, False)
集合成员测试in
:元素是否在集合/列表/字符串内。
>>> 'e' in x
True
>>> 'e' in 'Camelot', 22 in [11, 22, 33]
(True, True)
集合操作还提供了与这些操作对应的方法:
>>> z = x.intersection(y) # 交集
>>> z
{'d', 'b'}
>>> z.add('SPAM') # 加入新的元素
>>> z
{'d', 'b', 'SPAM'}
>>> z.update(set(['X', 'Y'])) # 与集合合并(并集)
>>> z
{'Y', 'X', 'b', 'd', 'SPAM'}
>>> z.remove('b') # 删除一个元素
>>> z
{'Y', 'X', 'd', 'SPAM'}
集合可以用于len
、for
操作,但不适用于索引、分片。
集合操作对应的方法对任何可迭代类型有效:
>>> S = set([1, 2, 3])
>>> S | set([3, 4])
{1, 2, 3, 4}
>>> S | [3, 4]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for |: 'set' and 'list'
>>> S.union([3, 4])
{1, 2, 3, 4}
>>> S.union((3, 4))
{1, 2, 3, 4}
新旧版本的集合字面量
对于集合S = {1, 2, 3}
,新版本(Python2.7,Python3.X)这么显示:
>>> S
{1, 2, 3}
旧版本(Python 2.X)这么显示:
>>> S
set([1, 2, 3])
空集表示(因此字面量{}
的类型是字典):
>>> S - {1, 2, 3}
set()
不可变性限制与冻结集合
集合只能包含不变的对象类型。
>>> S = {1.23}
>>> S.add([1, 2, 3])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'
>>> S.add({'a': 1})
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'dict'
>>> S.add((1, 2, 3))
>>> S
{1.23, (1, 2, 3)}
我们可以调用内置的frozenset
,这种类型的集合不可改变。
Python 3.X和Python 2.7中的集合推导
集合推导会运行一个循环并在每次迭代时收集一个表达式的结果,通过一个循环变量访问当前的迭代值以用于集合表达式中。
>>> {x ** 2 for x in [1, 2, 3, 4]}
{16, 1, 4, 9}
在这个表达式中,循环部分在右侧,集合体表达式在左侧(x ** 2)
。意思是:对于列表[1, 2, 3, 4]
中的每一个x
,给出包含x
平方的一个新集合。推导式也适用于迭代其他类型的对象(如字符串)。
为什么使用集合
去除集合体中的重复
>>> L = [1, 1, 4, 5, 1, 4]
>>> set(L)
{1, 4, 5}
>>> list(set(L))
[1, 4, 5]
提取可迭代对象的差异,借助集合完成顺序无关的等价性测试。
>>> set(dir(bytes)) - set(dir(bytearray))
{'__bytes__', '__getnewargs__'}
>>> set(dir(bytearray)) - set(dir(bytes))
{'insert', 'reverse', '__delitem__', 'copy', 'extend', '__iadd__', 'pop', 'append', '__imul__', 'clear', 'remove', '__alloc__', '__setitem__'}
>>> L1 = [1, 5, 2, 4, 3]
>>> L2 = [5, 1 ,2, 3, 4]
>>> L1 == L2
False
>>> set(L1) == set(L2)
True
布尔型
Python通过判断表达式的真假得到布尔值。
布尔型实际上是特殊的整数类型,True
对应1,False
对应0。
>>> True + 4
5
>>> False + 4
4
数值扩展
NumPy可以处理更复杂的数值类型,如向量、矩阵。
标签:
相关文章
最新发布
- 【Python】selenium安装+Microsoft Edge驱动器下载配置流程
- Python 中自动打开网页并点击[自动化脚本],Selenium
- Anaconda基础使用
- 【Python】成功解决 TypeError: ‘<‘ not supported between instances of ‘str’ and ‘int’
- manim边学边做--三维的点和线
- CPython是最常用的Python解释器之一,也是Python官方实现。它是用C语言编写的,旨在提供一个高效且易于使用的Python解释器。
- Anaconda安装配置Jupyter(2024最新版)
- Python中读取Excel最快的几种方法!
- Python某城市美食商家爬虫数据可视化分析和推荐查询系统毕业设计论文开题报告
- 如何使用 Python 批量检测和转换 JSONL 文件编码为 UTF-8
点击排行
- 版本匹配指南:Numpy版本和Python版本的对应关系
- 版本匹配指南:PyTorch版本、torchvision 版本和Python版本的对应关系
- Python 可视化 web 神器:streamlit、Gradio、dash、nicegui;低代码 Python Web 框架:PyWebIO
- 相关性分析——Pearson相关系数+热力图(附data和Python完整代码)
- Python与PyTorch的版本对应
- Anaconda版本和Python版本对应关系(持续更新...)
- Python pyinstaller打包exe最完整教程
- Could not build wheels for llama-cpp-python, which is required to install pyproject.toml-based proj