Python实践提升-数值与字符串

Python实践提升-数值与字符串
  现代人的生活离不开各种数字。人的身高是数字,年龄是数字,银行卡里的余额也是数字。大家同样离不开的还有文字。网络上的文章、路边的指示牌,以及你正在阅读的这本书,都是由文字构成的。

我们离不开数字和文字,正如同编程语言离不开“数值”与“字符串”。两者几乎是所有编程语言里最基本的数据类型,也是我们通过代码连接现实世界的基础。

对于这两种基础类型,Python 展现了它一贯的简单易用的特点。拿整型(integer)来说,在 Python 里使用整型,你不需要了解“有符号”“无符号”“32 位”“64 位”这些令人头疼的概念。不论多大的数字都能直接用,不必担心任何溢出问题:

#无符号 64 位整型的最大值(unsigned int64)
>>> 2 ** 64 - 1
18446744073709551615

#直接乘上 10000 也没问题,永不溢出!
>>> 18446744073709551615 * 10000
184467440737095516150000

和数字一样,Python 里的字符串(string)也很容易上手 1。它直接兼容所有的 Unicode 字符,处理起中文来非常方便:

1准确来说,是 Python 3 版本后的字符串容易上手。要处理好 Python 2 及之前版本中的字符串还是有些难度的。

>>> s = 'Hello, 中文'
>>> type(s)
<class 'str'>

#打印中文
>>> print(s)
Hello, 中文

除了上面的字符串类型(str),有时我们还需要同字节串类型(bytes)打交道。在本章的基础知识板块,我会简单介绍二者的区别,以及如何在它们之间做转换。

接下来,我们就从这两种最基础的数据类型开始,踏上探索 Python 对象世界的旅程吧!

2.1 基础知识
  本节将介绍与数值和字符串有关的基础知识,内容涵盖浮点数的精度问题、字符串与字节串的区别,等等。

2.1.1 数值基础
  在 Python 中,一共存在三种内置数值类型:整型(int)、浮点型(float)和复数类型(complex)。创建这三类数值很简单,代码如下所示:

#定义一个整型
>>> score = 100
#定义一个浮点型
>>> temp = 37.2
#定义一个复数
>>> com = 1+2j

在大多数情况下,我们只需要用到前两种类型:int 与 float。二者之间可以通过各自的内置方法进行转换:

#将浮点数转换为整型
>>> int(temp)
37

#将整型转换为浮点型
>>> float(score)
100.0

在定义数值字面量时,如果数字特别长,可以通过插入 _ 分隔符来让它变得更易读:

#以"千"为单位分隔数字
>>> i = 1_000_000
>>> i + 10
1000010

正如本章开篇所说,Python 里的数值类型十分让人省心,你大可随心所欲地使用,一般不会碰到什么奇怪的问题。不过,浮点数精度问题是个例外。

浮点数精度问题
  如果你在 Python 命令行里输入 0.1 + 0.2,你会看到这样的“奇景”:

>>> 0.1 + 0.2
0.30000000000000004

一个简单的小数计算,为何会产生这么奇怪的结果?这其实是一个由浮点数精度导致的经典问题。

计算机是一个二进制的世界,它能表示的所有数字,都是通过 0 和 1 两个数模拟而来的(比如二进制的 110 代表十进制的 6)。这套模拟机制在表示整数时,尚能勉强应对,一旦我们需要小于 1 的浮点数时,计算机就做不到绝对的精准了。

但是,不提供浮点数肯定是不行的。为此,计算机只好“尽力而为”:取一个固定精度来近似表示小数——Python 使用的是“双精度”(double precision)2。这个精度限制就是 0.1 + 0.2 的最终结果多出来 0.000…4 的原因。

2具体来说,是符合 IEEE-754 规范的双精度,它使用 53 个比特的精度来表达十进制浮点数。

为了解决这个问题,Python 提供了一个内置模块:decimal。假如你的程序需要精确的浮点数计算,请考虑使用 decimal.Decimal 对象来替代普通浮点数,它在做四则运算时不会损失任何精度:

>>> from decimal import Decimal
#注意:这里的 '0.1' 和 '0.2' 必须是字符串
>>> Decimal('0.1') + Decimal('0.2')
Decimal('0.3')

在使用 Decimal 的过程中,大家需要注意:必须使用字符串来表示数字。如果你提供的是普通浮点数而非字符串,在转换为 Decimal 对象前就会损失精度,掉进所谓的“浮点数陷阱”:

>>> Decimal(0.1)
Decimal('0.1000000000000000055511151231257827021181583404541015625')

如果你想了解更多浮点数相关的内容,可查看 Python 官方文档中的“15. Floating Point Arithmetic: Issues and Limitations”,其中的介绍非常详细。
2.1.2 布尔值其实也是数字
  布尔(bool)类型是 Python 里用来表示“真假”的数据类型。你肯定知道它只有两个可选值:True 和 False。不过,你可能不知道的是:布尔类型其实是整型的子类型,在绝大多数情况下,True 和 False 这两个布尔值可以直接当作 1 和 0 来使用。

就像这样:

>>> int(True), int(False)
(1, 0)
>>> True + 1
2

#把 False 当除数的效果和 0 一样
>>> 1 / False
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ZeroDivisionError: division by zero

布尔值的这个特点,最常用来简化统计总数操作。

假设有一个包含整数的列表,我需要计算列表里一共有多少个偶数。正常来说,我得写一个循环加分支结构才能完成统计:

numbers = [1, 2, 4, 5, 7]

count = 0
for i in numbers:
    if i % 2 == 0:
        count += 1

print(count)
#输出:2

但假如利用“布尔值可作为整型使用”的特性,一个简单的表达式就能完成同样的事情:

count = sum(i % 2 == 0 for i in numbers)

❶ 此处的表达式 i % 2 == 0 会返回一个布尔值结果,该结果随后会被当成数字 0 或 1 由 sum() 函数累加求和

2.1.3 字符串常用操作
  本节介绍一些与字符串有关的常用操作。

把字符串当序列来操作

字符串是一种序列类型,这意味着你可以对它进行遍历、切片等操作,就像访问一个列表对象一样:

>>> s = 'Hello, world!'
>>> for c in s:...     print(c)
...
H
...
d
!
>>> s[1:3]'el'

❶ 遍历一个字符串,将会逐个返回每个字符

❷ 对字符串进行切片

假如你想反转一个字符串,可以使用切片操作或者 reversed 内置方法:

>>> s[::-1]'!dlrow ,olleH'
>>> ''.join(reversed(s))'!dlrow ,olleH'

❶ 切片最后一个字段使用 -1,表示从后往前反序

❷ reversed 会返回一个可迭代对象,通过字符串的 .join 方法可以将它转换为字符串

字符串格式化

Python 语言有一个设计理念:“任何问题应有一种且最好只有一种显而易见的解决方法。”3如果把这句话放到字符串格式化领域,似乎就有点儿难以自圆其说了。

在当前的主流 Python 版本中,至少有三种主要的字符串格式化方式。

(1) C 语言风格的基于百分号 % 的格式化语句:‘Hello, %s’ % ‘World’。

(2) 新式字符串格式化(str.format)方式(Python 2.6 新增):“Hello, {}”.format (‘World’)。

(3) f-string 字符串字面量格式化表达式(Python 3.6 新增):name = ‘World’; f’Hello, {name}'。

第一种字符串格式化方式历史最为悠久,但现在已经很少使用。相比之下,后两种方式正变得越来越流行。从个人体验来说,f-string 格式化方式用起来最方便,是我的首选。和其他两种方式比起来,使用 f-string 的代码多数情况下更简洁、更直观。

举个例子:

username, score = 'andy', 100
#1. C 语言风格格式化
print('Welcome %s, your score is %d' % (username, score))
#2. str.format
print('Welcome {}, your score is {:d}'.format(username, score))

#3. f-string,最短最直观
print(f'Welcome {
     
     username}, your score is {
     
     score:d}')
#输出:
#Welcome andy, your score is 100
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值