字符编码
我们要清楚,计算机最开始的表达都是由二进制而来
我们要想通过二进制来表示我们熟知的字符看看以下的变化
例如: 1
的二进制编码为 0000 0001
我们通过A这个字符,让其在计算机内部存储(现如今,A 字符在地址通常表示为65)
现在拿A举例:
在计算机内部 A字符,它本身表示为 65这个数,在计算机底层会转为二进制码
也意味着A字符在底层表示为 1000001
通过这样的字符表示进行转换,逐步发展为拥有127个字符的编码存储到计算机中,这个编码表也被称为ASCII
编码。
但随时代变迁,ASCII
编码逐渐暴露短板,全球有上百种语言,光是ASCII编码并不能够满足需求
所以拥有更加庞大字符的 Unicode
字符集诞生。Unicode把所有语言都统一到一套编码里,如今现代操作系统和大多数编程语言都直接支持Unicode。
Unicode通过将字符分隔表示,通过多位数字表示为一个字符。
UTF-8
在Unicode基础上增加了多个二进制位涵盖了更多的字符
字符 | ASCII | Unicode | UTF-8 |
---|---|---|---|
A | 01000001 | 00000000 01000001 | 01000001 |
中 | 01001110 00101101 | 11100100 10111000 10101101 |
Python中的字符串
在Python3版本中,字符串都是以Unicode编码的(支持多语言)
对于==单个字符串==的编码,Python提供了ord()
函数,该函数用于获取字符的整数表示
chr()
函数把编码转换为对应的字符
a1 = "a"
print(ord(a1)) # 97
a2 = "99"
print(chr(int(a2))) # c
如果知道字符的整数编码,还可以用十六进制这么写str
:
a3 = '\u4e2d\u6587'
print(a3) # '中文'
通过编码表示字符,本身写法就是等价的。
由于Python字符串类型是str
,在内存中以Unicode表示,一个字符对应若干个字节。
当在网络中获取文件流中传输,需要将字符转为单位字节bytes
这与java、go语言一致,本身字符串不能在复杂场景下直接传递,需要转为字节码传输
在Python中,bytes 字节,通过b
前缀的单引号或双引号显示
a3 = b"Hello"
print(a3) # b'Hello'
虽然不加前缀 b
和 b'Hello'
的表示一样,但是bytes
的每个字符都只占用一个字节
以Unicode表示的str
通过encode()
方法可以编码为指定的bytes
。
a4 = "测试".encode("utf-8") # 编码
print(a4)
a5 = "test测试".encode("ASCII") # 解码
print(a5)
b'\xe6\xb5\x8b\xe8\xaf\x95'
Traceback (most recent call last):
File "E:\Python\Python基础\dataType.py", line 62, in
a5 = "test测试".encode("ASCII") # 解码~~~~~~~~~~~~~~~~~^^^^^^^^^
UnicodeEncodeError: 'ascii' codec can't encode characters in position 4-5: ordinal not in range(128)
报错了?这是因为ASCII编码的内容区间无法表示中文字符,这就保持了 ordinal not in range(128)
这个错误
在bytes
中,无法显示为ASCII字符的字节,用\x##
显示。
如果bytes
中只有一小部分无效的字节,可以传入errors='ignore'
忽略错误的字节:
c1 = b'\xe4\xb8\xad\xff'.decode('utf-8', errors='ignore')
print(c1) # '中'
要计算 str
包含多少个字符,可以用len()
函数
c2 = len("ABC")
print(c2) # 3
字符串格式化
在正式开发中,我们需要学会如何格式化字符串
即:用变量代替字符串输出(动态文本)
在Python中,采用的格式化方式和C语言是一致的,用%
实现,举例如下:
a6 = "Hello %s" % "World" # %s 字符串
print(a6) # Hello World
a7 = "Hello %d" % 123 # %d 整数
print(a7) # Hello 123
a8 = "Hello %f" % 123.123 # %f 浮点数
print(a8) # Hello 123.123000
a9 = "Hello %e" % 123.123 # %e 科学计数法
print(a9) # Hello 1.231230e+02
a10 = "hello %s,my name is %s" % ("xiaowang","zhangsan") # %s 字符串
print(a10) # hello xiaowang,my name is zhangsan
%
运算符就是用来格式化字符串的。在字符串内部,%s
表示用字符串替换,%
表示用整数替换,有多少个%?
占位符,在后面的()
中,就跟着多少个变量(值)。
()
中的值顺序是与占位符的位置一一对应的。- 若只有一个占位符,
()
括号可以省略
而在Python中,如果你不太确定应该用什么,%s
永远起作用,它会把任何数据类型转换为字符串:
a11 = "hello %s,this is %s" % ("xiaowang",True)
print(a11) # hello xiaowang,this is True
f-string
格式化字符串的方法是使用以f
开头的字符串,称之为f-string
,它和普通字符串不同之处在于,字符串如果包含{xxx}
,就会以对应的变量替换:
a12 = 2.44123123123
a13 = 1.5 * a12 ** 2
a14 = f'The number is {a12} and the result is {a13:.2f}' # f-string
print(a14) # The number is 2.44123123123 and the result is 8.94
上述代码中,{r}
被变量r
的值替换,{s:.2f}
被变量s
的值替换,并且:
后面的.2f
指定了格式化参数(即保留两位小数),因此,{s:.2f}
的替换结果是19.62
。
拓展:
%.xf
和{变量:.xf}
其中x
代表任意整数这两种写法其作用是为
%
和变量
裁切小数,具体保留位数是x
规定在Python中
*
代表乘法;**
代表次方(幂运算);如
2 ** 2
这行代码所表示的就是4
也就是2的2次方
list 集合
Python内置的数据类型:list 列表。
list是一种有序的集合,可以随时添加和删除其中的元素
设一个班级中存在有zhangsan、lisi、wangwu
三名学生,这时就可以通过list集合进行存储
classA = ["zhangsan","lisi","wangwu"] # 列表
print(classA) # ['zhangsan', 'lisi', 'wangwu']
print(classA[0]) # zhangsan
print(classA[1]) # lisi
print(classA[2]) # wangwu
print(classA[-1]) # wangwu
print(classA[-2]) # lisi
print(len(classA)) # 3
- 通过
len()
函数可以获取list元素的个数
当索引超出了范围时,Python会报一个IndexError
错误,所以,要确保索引不要越界,记得最后一个元素的索引是len(classmates) - 1
。
如果要取最后一个元素,除了计算索引位置外,还可以用-1
做索引,直接获取最后一个元素:
classA[-1] # wangwu
你可以理解为正数获取元素就是从头开始获取
负数获取元素就是从最后开始倒叙依次获取
print(classA[-1]) # wangwu
print(classA[-2]) # lisi
print(classA[-3]) # zhangsan
classA[-4]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: list index out of range
list操作
- append(T)
该函数可以为list集合在末尾追加一个元素
arr = [1,2,3,576,1,23,6,8,1]
arr.append("元素A") # 添加元素
print(arr) # [1, 2, 3, 576, 1, 23, 6, 8, 1, '元素A']
在Python中不用担心类型转换问题,包括集合内部也是一样的
例如示例中明显是一个整数集合,但是依旧可以添加字符串
这样操作在Java、Go语言中是不可以的。
- insert(number,T)
向list集合的指定索引处,添加一个元素
arr.insert(2,"元素B") # 插入元素
print(arr) # [1, 2, '元素B', 3, 576, 1, 23, 6, 8, 1, '元素A']
- pop() 或 pop(number)
该方法若不指定索引位置,则默认删除集合的最后一个元素
而传入值后,则删除指定索引处的值
arr.pop() # 删除最后一个元素
print(arr) # [1, 2, '元素B', 3, 576, 1, 23, 6, 8, 1]
arr.pop(2) # 删除指定位置的元素
print(arr) # [1, 2, 3, 576, 1, 23, 6, 8, 1]
删除指定索引处的值,除了pop(number)
方法,还可以使用remove(number)
方法
arr.remove(1) # 删除指定元素
print(arr) # [2, 3, 576, 23, 6, 8, 1]
remove()方法,它计算的索引是从1开始
集合[number]
和集合[number:number]
这种集合的表示方式,还可以对索引对应的值进行更改
arr[5] = "替换元素" # 替换元素
print(arr) # [2, 3, 576, 23, 6, '替换元素', 1]
arr[1:3] = ["元素C","元素D"] # 替换元素
print(arr) # [2, '元素C', '元素D', 576, 23, '替换元素', 1]
arr[4:7] = ["元素E","元素F","元素G"] # 替换元素
print(arr) # [2, '元素C', '元素D', 576, '元素E', '元素F', '元素G', 1
arr[4:9] = ["元素E","元素F","元素G"] # 替换元素
print(arr) # [2, '元素C', '元素D', 1, '元素E', '元素F', '元素G']
需要注意第二种写法,当存在[number:number]之间的间隔存在多少个元素,而替换的值又不满足这么多的元素时,剩余元素会被清除掉。
- sort()
当数组内全部都是数值时,可以使用该方法进行排序
arr2 = [1,2,55,122,7,34,97,976,234,123,2342]
arr.sort() # 排序
print(arr2) # [1, 2, 7, 34, 55, 97, 122, 234, 976, 123, 2342]
- clear()
该方法可以清空数组内的全部元素
arr.clear() # 清空列表
print(arr) # []
tuple 元组
另一种列表叫做元组:tuple
tuple和list是相似的。但是 tuple一旦初始化就不能修改了
你可以正常的读取元组中的值,但是不能将它赋值成另外的元素
classA = ("zhangsan","lisi","wangwu") # 元组
print(classA) # ('zhangsan', 'lisi', 'wangwu') # 元组不能修改
classA[0] = "xiaowang" # 元组不能修改
## 打印
('zhangsan', 'lisi', 'wangwu')
Traceback (most recent call last):
File "E:\Python\Python基础\dataType.py", line 128, in <module>
classA[0] = "xiaowang" # 元组不能修改
~~~~~~^^^
TypeError: 'tuple' object does not support item assignment
若进行修改,则会报错。
因为tuple不可变的特性,所以代码更加安全,能用tuple就尽量使用tuple
当我们需要保存一个元素的tuple元组时,我们需要这样声明
t = (1,)
为什么要加,
号?因为在Python原本的语法中()
是表示数学公式中的小括号,亦或者表示限定作用域范围。这就会产生歧义。我们需要添加一个,
号来标明这个()
内部是一个tuple。
虽然元组不可变,但是元组内部存储的数组是可变的,它没有深绑定行为。在内存地址方面来说,元组存储的数组是指向的另一个内存地址,这个地址不受到Python的绑定
arr3 = (1,2,5,22,['元素A','元素B']) # 元组可以包含列表
print(arr3) # (1, 2, 5, 22, ['元素A', '元素B'])
arr3[4][0] = "元素C" # 元组可以包含列表,列表可以修改
print(arr3) # (1, 2, 5, 22, ['元素C', '元素B'])
😎🙌Python专栏前篇回顾~~
(Python基础)新时代语言!一起学习Python吧!(一):认识Python、Py解释器作用;编写第一个Python程序;Python中的基本数据结构
💕👉博客专栏
- Golang专栏-包含基础、Gin、Goam等知识
- 云原生专栏-包含k8s、docker等知识
- 从0开始学习云计算-华为HCIP证书
- JUC专栏-带你快速领悟JUC的知识!
- JVM专栏-深入Java虚拟机,理解JVM的原理
- 基于Java研究 数据结构与算法-包含贪心算法、加权图、最短路径算法等知识
- Docker专栏-上手热门容器技术Docker
- SpringBoot专栏-学习SpringBoot快速开发后端
- 项目管理工具的学习-设计技术:Maven、Git、Gradle等相关管理工具
- JavaSE-全面了解Java基础
- JS专栏-使用JS作的一部分实例~
- 使用CSS所作的一部分案例