目录

  • 0. 前言
  • 1. 变量及命名
  • 1.1 变量
  • 1.2 命名规范
  • 1.3 命名方式
  • 2. 数据类型
  • 2.1 数字类型(Numeric Types)
  • 2.1.1 int(整数)
  • 2.1.2 float(浮点数)
  • 2.1.3 complex(复数)
  • 2.2 序列类型(Sequence Types)
  • 2.2.1 str(字符串)
  • 2.2.2 list(列表)
  • 2.2.3 列表操作符
  • 2.2.4 tuple(元组)
  • 2.2.5 range(范围)
  • 2.3 集合类型(Set Types)
  • 2.3.1 set(集合)
  • 2.3.2 frozenset(冻结集合)
  • 2.3.3 集合常见的操作方法
  • 2.4 映射类型(Mapping Types)
  • 2.4.1 字典
  • 2.4.2 字典内置函数与方法
  • 2.5 布尔类型(Boolean Type)
  • 2.5.1 布尔类型定义
  • 2.5.2 布尔运算
  • 2.6 二进制类型(Binary Types)
  • 2.6.1 字节
  • 2.6.2 字节的编码和解码
  • 2.6.3 可变字节数组
  • 2.6.4 可变字节数组的编码和解码
  • 2.7 特殊类型
  • 2.8 自定义类型



(2)深入探索Python:完整剖析基础数据类型_开发语言

0. 前言

Python作为一种高级编程语言,提供了多种基本数据类型用于存储和操作不同的数据。
理解这些基本数据类型对于编写高效、可靠的Python代码至关重要。

如果您已经安装了python及其相关工具,我们可以开始学习它的数据类型啦!

注:您可以在python命令行、可以在VS Code、可以在PyCharm,也可以在colab中,任何你喜欢的地方来执行下面学习的内容!
无论哪种方式,您都可以在专栏中找到哦!

1. 变量及命名

1.1 变量

在Python中,变量是用来存储数据的容器。我们可以给变量赋值,并使用这些值进行计算或操作。Python支持多种数据类型,包括整数、浮点数、字符串等。

# 定义变量
age = 10
name = "Alice"

# 打印变量
print("My age is", age)
print("My name is", name)

在上面的例子中,我们定义了两个变量agename,并分别赋值为整数10和字符串"Alice"。然后,我们使用print()函数将变量的值打印出来。

1.2 命名规范

在Python中,变量与常量的命名要遵守一定的规则,以下是一些常见的命名规范:

  • 变量名通常由字母、数字、下划线组成,且第一个字母必须为字母或下划线,不能为数字;
  • 变量名大小写敏感,如age与Age是两个不同的变量;
  • Python的关键字不能作为变量名使用,Python的关键字包括:False、def、if、raise、None、del、import、return、True、elif、in、try、and、else、is、while、as、except、lambda、with、assert、finally、nonlocal、yield、break、for、not、class、from、or、continue、global、pass等。

1.3 命名方式

Python常用的命名方式有三种:

  • 小驼峰式命名:第一个单词首字母小写,之后的单词首字母大写,如userName等,通常用于定义变量、方法名。
  • 大驼峰式命名:每个单词首字母都大写,如GameStore等,通常用于定义类名。
  • 下划线连接命名:用下划线“_”连接每个单词,如age_box等,小写的通常用于定义变量名,大写通常用于定义常量。

2. 数据类型

Python 是一种动态类型语言,即变量的类型在运行时可以改变。
Python 中有多种数据类型,这些类型可以大致分为以下几类:

2.1 数字类型(Numeric Types)

2.1.1 int(整数)

例如,100, -20, 0

# 整数
integer_num = 100
print(integer_num, type(integer_num))  # 输出: 100 <class 'int'>

2.1.2 float(浮点数)

例如,3.14, -9.01

# 浮点数
float_num = 3.14
print(float_num, type(float_num))  # 输出: 3.14 <class 'float'>

2.1.3 complex(复数)

例如,3+4j(实部是3,虚部是4,j为虚部单位)

# 复数
z = 3 + 4j
 
# 打印复数及其实部和虚部
print(z)
print("实部:", z.real)
print("虚部:", z.imag)
 
# 修改复数的实部和虚部
# 也可以用z = complex(5, 6) 来设置实部和虚部
z.real = 5
z.imag = 6
print("修改后的复数:", z)

2.2 序列类型(Sequence Types)

2.2.1 str(字符串)

例如,“Hello, World!”

# 字符串
string_var = "Hello, World!"
print(string_var, type(string_var))  # 输出: Hello, World! <class 'str'>

2.2.2 list(列表)

列表是Python中最基本的数据结构。列表中的每个元素都分配一个数字 - 它的位置,或索引,第一个索引是0,第二个索引是1,依此类推。也可以使用方括号的形式截取字符。
例如,列表[1, 2, 3, 4, 5]

# 列表
list_var = [1, 2, 3, 4, 5]
print(list_var, type(list_var))  # 输出: [1, 2, 3, 4, 5] <class 'list'>
print(list_var[0], list_var[1], list_var[2], list_var[3], list_var[4])  # 输出: 1, 2, 3, 4, 5
print("list_var[1:4]: ", list_var[1:4]) # 输出:list_var[1:4]:  [2, 3, 4]
print(list_var[-2]) # 输出:4
print(list_var[1:]) # 输出:[2, 3, 4, 5]

# 更新第二个值为9
list_var[1] = 9
print(list_var[1]) # 输出:9

# 删除第三个值
del list_var[2]
print(list_var) # 输出:[1, 9, 4, 5]

此外,列表包含以下方法:
list.append(obj):在列表末尾添加新的对象
list.count(obj):统计某个元素在列表中出现的次数
list.extend(seq):在列表末尾一次性追加另一个序列中的多个值(用新列表扩展原来的列表)
list.index(obj):从列表中找出某个值第一个匹配项的索引位置
list.insert(index, obj):将对象插入列表
list.pop(obj=list[-1]):移除列表中的一个元素(默认最后一个元素),并且返回该元素的值
list.remove(obj):移除列表中某个值的第一个匹配项
list.reverse():反向列表中元素
list.sort([func]):对原列表进行排序

及以下函数
cmp(list1, list2):比较两个列表的元素
len(list):列表元素个数
max(list):返回列表元素最大值
min(list):返回列表元素最小值
list(seq):将元组转换为列表

2.2.3 列表操作符

len():长度
+:组合列表
*:重复
in:值在列表中是否存在
for x in 列表:迭代
例如:列表[1, 2, 3, 4, 5]

# 列表
list_var = [1, 2, 3, 4, 5]
print(len(list_var)) # 输出:5
print(list_var+[7, 8]) # 输出:[1, 2, 3, 4, 5, 7, 8]
print(list_var*2) # 输出:[1, 2, 3, 4, 5, 1, 2, 3, 4, 5]
print(2 in list_var) # 输出:True
for x in list_var:
  print(x)           # 从1-5逐行输出

2.2.4 tuple(元组)

Python 的元组与列表类似,主要有以下几处不同:

  • 元组的元素不能修改
  • 元组使用小括号
    元组创建很简单,只需要在括号中添加元素,并使用逗号隔开即可,例如,(1, 2, 3)
    元组中只包含一个元素时,需要在元素后面添加逗号,例如,tup1 = (50,)
    任意无符号的对象,以逗号隔开,默认为元组,例如, ‘abc’, -4.24e93, 18+6.6j, ‘xyz’
# 元组
tuple_var = (1, 2, 3)
print(tuple_var, type(tuple_var))  # 输出: (1, 2, 3) <class 'tuple'>
print(tuple_var[0], tuple_var[1], tuple_var[2]) # 输出:1,2,3
print(tuple_var + (4, 5)) # 输出:(1, 2, 3, 4, 5)
del tuple_var # 删除元组

print 'abc', -4.24e100, 1+2.1j, 'xyz' # 输出:abc -4.24e+100 (1+2.1j) xyz

此外,元组包含以下函数
cmp(tuple1, tuple2):比较两个元组的元素
len(tuple):列表元组个数
max(tuple):返回元组最大值
min(tuple):返回元组最小值
tuple(list):将列表转换为元组

2.2.5 range(范围)

range()是python的一个内置函数,用来创建一个整数序列,常用于for循环中。
range(start, stop, step) ,如果值为value,则表示 start <= value < stop,间隔为step
例如:
range(10) 生成一个从 0 到 9 的整数序列
range(0,5) 生成0-5之间的数,中间间隔1,即:0,1,2,3,4
range(0,5,2) 生成0-5之间的数,中间间隔2,即:0,2,4

# 范围
range_var = range(10)
print(list(range_var), type(range_var))  # 输出: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] <class 'range'>
range(0,5)    # 等价于 range(0,5,1),返回[0,1,2,3,4]
range(0,5,2)  # 返回[0,2,4]

# 按行输出0 - 10
for i in range(10):
	print(i);

2.3 集合类型(Set Types)

2.3.1 set(集合)

创建集合使⽤ {} 或 set() , 但是如果要创建空集合只能使⽤ set() ,因为 {} ⽤来创建空字典。
集合的特征:

  • 集合可以去掉重复数据;
  • 集合数据是⽆序的,故不⽀持下标
    例如,{1, 2, 3}(集合是无序且不重复的)
# 集合
set_var = {1, 2, 3}
print(set_var, type(set_var))  # 输出: {1, 2, 3} <class 'set'>
s3 = set('abcdefge')
print(s3) # 输出 {'b', 'e', 'c', 'd', 'f', 'g', 'a'},自动过滤重复的e

2.3.2 frozenset(冻结集合)

类似于集合,但它是不可变的,因此不存在update等修改的方法。

# 冻结集合
frozenset_var = frozenset({1, 2, 3})
print(frozenset_var, type(frozenset_var))  # 输出: frozenset({1, 2, 3}) <class 'frozenset'>

2.3.3 集合常见的操作方法

Python 的集合(set)是一种无序且不包含重复元素的数据类型。集合提供了很多有用的操作,以下是一些常见的集合操作方法:

  1. 创建集合
my_set = {1, 2, 3, 4}
# 或者使用 set() 函数创建集合
my_set = set([1, 2, 2, 3, 4, 4])  # 重复元素会被自动去重
  1. 添加元素
my_set.add(5)  # 添加单个元素
my_set.update([6, 7])  # 添加多个元素
  1. 移除元素
my_set.remove(3)  # 移除指定的元素,如果该元素不存在则抛出 KeyError
my_set.discard(4)  # 移除指定的元素,如果该元素不存在则不抛出任何异常
my_set.pop()  # 移除并返回集合中的任意一个元素,如果集合为空则抛出 KeyError
my_set.clear()  # 移除集合中的所有元素
  1. 判断元素是否存在
if 3 in my_set:
    print("3 is in the set.")
else:
    print("3 is not in the set.")
  1. 集合的交集、并集、差集和对称差集
set1 = {1, 2, 3, 4}
set2 = {3, 4, 5, 6}

# 交集
intersection = set1 & set2  # 或 set1.intersection(set2)
print(intersection)  # 输出: {3, 4}

# 并集
union = set1 | set2  # 或 set1.union(set2)
print(union)  # 输出: {1, 2, 3, 4, 5, 6}

# 差集(集合1中存在而集合2中不存在的元素)
difference = set1 - set2  # 或 set1.difference(set2)
print(difference)  # 输出: {1, 2}

# 对称差集(存在于一个集合中但不同时存在于两个集合中的元素)
symmetric_difference = set1 ^ set2  # 或 set1.symmetric_difference(set2)
print(symmetric_difference)  # 输出: {1, 2, 5, 6}
  1. 集合的交集更新、并集更新和差集更新
set1 = {1, 2, 3, 4}
set2 = {3, 4, 5, 6}

# 交集更新(保留两个集合的交集)
set1.intersection_update(set2)  # set1 &= set2
print(set1)  # 输出: {3, 4}

# 并集更新(更新集合1,使其包含集合1和集合2的所有元素)
set1 = {1, 2, 3, 4}
set1.update(set2)  # set1 |= set2
print(set1)  # 输出: {1, 2, 3, 4, 5, 6}

# 差集更新(移除集合1中存在于集合2的元素)
set1 = {1, 2, 3, 4}
set1.difference_update(set2)  # set1 -= set2
print(set1)  # 输出: {1, 2}
  1. 判断两个集合是否相等
set1 = {1, 2, 3}
set2 = {1, 2, 3}
set3 = {2, 3, 4}
print(set1 == set2)  # 输出: True
print(set1 == set3)  # 输出: False
  1. 获取集合的大小
my_set = {1, 2, 3, 4}
print(len(my_set))  # 输出: 4
  1. 集合是否是另一个集合的子集或超集
set1 = {1, 2, 3}

继续Python集合常见的操作方法

  1. 迭代和遍历集合
    使用for循环可以遍历集合中的所有元素。
my_set = {1, 2, 3, 4}
for element in my_set:
    print(element)  # 输出集合中的每个元素
  1. 集合的转换
  • 集合转列表:使用list()函数可以将集合转换为列表。
my_set = {1, 2, 3, 4}
my_list = list(my_set)  # 转换后的列表可能顺序与集合不同
print(my_list)  # 输出列表
  • 列表转集合:使用set()函数可以将列表转换为集合,会自动去除重复元素。
my_list = [1, 2, 2, 3, 4, 4]
my_set = set(my_list)
print(my_set)  # 输出集合
  1. 其他集合常用方法
  • issubset():判断一个集合是否是另一个集合的子集。
  • issuperset():判断一个集合是否是另一个集合的超集。
  • symmetric_difference_update():用两个集合的对称差集更新集合。
set1 = {1, 2, 3}
set2 = {2, 3, 4}
print(set1.issubset(set2))  # False
print(set2.issuperset(set1))  # True
set1.symmetric_difference_update(set2)
print(set1)  # 输出:{1, 4},因为对称差集包含存在于一个集合但不同时存在于两个集合中的元素
  1. 检查元素是否为空
    使用if not my_set:可以检查一个集合是否为空。
my_set = {}  # 注意这里实际上会创建一个空字典,而不是空集合
if not my_set:  # 这里会评估为True,但这不是检查集合是否为空的正确方法
    print("The set is empty.")

my_set = set()  # 正确的空集合创建方法
if not my_set:
    print("The set is empty.")  # 正确输出:The set is empty.

请注意,在Python中,空集合必须使用set()函数或frozenset()函数来创建,直接使用空的大括号{}会被解释为空字典。

2.4 映射类型(Mapping Types)

在Python中,映射类型(Mapping Type)通常指的是可以存储键值对(key-value pair)的数据结构。其中,最常用的映射类型是字典(dictionary)。

2.4.1 字典

字典是一个无序、可变、可存储任意类型数据的集合。
字典由键值对key:value组成,键(key)必须是唯一的、不可变的(如整数、浮点数、字符串、元组等),而值(value)可以是任意类型的数据,每个键值对之间用逗号 , 分割,整个字典包括在花括号 {} 中 ,如下所示:

# 字典
dict_var = {"name": "Alice", "age": 30}
print(dict_var, type(dict_var))  # 输出: {'name': 'Alice', 'age': 30} <class 'dict'>
print(dict_var["name"]) # 输出:Alice
dict_var["age"] = 29  #更新
dict_var['School'] = "Kongjiang" # 添加
del dict_var["age"]  #删除字段元素age

2.4.2 字典内置函数与方法

字典包含以下方法:
dict.clear(): 删除字典内所有元素
dict.copy():返回一个字典的浅复制
dict.fromkeys(seq[, val]): 创建一个新字典,以序列 seq 中元素做字典的键,val 为字典所有键对应的初始值
dict.get(key, default=None): 返回指定键的值,如果值不在字典中返回default值
dict.has_key(key): 如果键在字典dict里返回true,否则返回false。Python3 不支持。
dict.items(): 以列表返回可遍历的(键, 值) 元组数组。
dict.keys():以列表返回一个字典所有的键
dict.setdefault(key, default=None):和get()类似, 但如果键不存在于字典中,将会添加键并将值设为default
dict.update(dict2):把字典dict2的键/值对更新到dict里
dict.values():以列表返回字典中的所有值
pop(key[,default]):删除字典给定键 key 所对应的值,返回值为被删除的值。key值必须给出。 否则,返回default值。
popitem():返回并删除字典中的最后一对键和值。

及以下函数
cmp(dict1, dict2): 比较两个字典元素。
len(dict): 计算字典元素个数,即键的总数。
str(dict): 输出字典可打印的字符串表示。
type(variable): 返回输入的变量类型,如果变量是字典就返回字典类型。

2.5 布尔类型(Boolean Type)

2.5.1 布尔类型定义

在Python中,布尔类型(Boolean type)是一种内置的数据类型,用于表示逻辑上的真(True)和假(False)。

# 布尔值
bool_var = True
print(bool_var, type(bool_var))  # 输出: True <class 'bool'>

2.5.2 布尔运算

Python支持几种常见的布尔运算符,包括 and(与)、or(或)和 not(非)。

result_and = True and False  # 结果为 False
result_or = True or False   # 结果为 True
result_not = not True       # 结果为 False
 
print(result_and)  # 输出: False
print(result_or)   # 输出: True
print(result_not)  # 输出: False

注:在需要布尔值的上下文中(例如条件语句、循环控制等),Python会将某些值隐式地转换为布尔值。例如,空值(如 None、空列表 []、空字典 {}、空字符串 ‘’ 等)在布尔上下文中被视为 False,而非空值则被视为 True。

2.6 二进制类型(Binary Types)

在Python中,二进制数据并不是作为一个单独的数据类型存在,但Python提供了多种方式来处理二进制数据。

2.6.1 字节

Python通常使用字节序列(也称为字节对象或字节串)处理二进制数据,即:通过bytes类型来表示。
bytes类型是一个不可变的字节序列,它是Python 3中的一个内置数据类型。
bytes对象通常用于在低级操作(如文件I/O网络通信等)中表示二进制数据。
以下是关于bytes类型的定义方法:

# 从字符串直接转换
bytes_var = b'Hello'
print(bytes_var, type(bytes_var))  # 输出: b'Hello' <class 'bytes'>

# 从字符串(必须是ASCII字符串)直接转换
b = bytes('hello', 'ascii')  
print(b)   # 输出: b'hello'

# 从一个整数列表(每个整数必须在0到255之间)转换
b = bytes([72, 101, 108, 108, 111])  
print(b)   # 输出: b'Hello'

注意:如果字符串包含非ASCII字符,你需要指定一个不同的编码,比如'utf-8'

以下是bytes对象操作方法示例:

b = bytes([72, 101, 108, 108, 111])
print(b[0])  # 输出: 72
print(b[1:4])  # 输出: b'ell'
  • len()函数用于获取字节数:
b = bytes([72, 101, 108, 108, 111])
print(len(b))  # 输出: 5
  • 使用+进行连接(虽然不常见,因为bytes是不可变的):
b1 = bytes([72, 101])
b2 = bytes([108, 108, 111])
b3 = b1 + b2  # 输出: b'Hello'
  • 使用in检查某个字节是否存在于bytes对象中:
b = bytes([72, 101, 108, 108, 111])
print(101 in b)  # 输出: True

2.6.2 字节的编码和解码

在Python中,经常需要将二进制数据和字符串之间进行转换。这通常涉及编码(将字符串转换为二进制数据)和解码(将二进制数据转换为字符串)的过程。

  • 编码(使用encode()方法):
s = 'Hello'
b = s.encode('utf-8')  # 输出: b'Hello'(注意:这里的输出取决于你的环境和'Hello'的具体内容)
  • 解码(使用decode()方法):
b = bytes([72, 101, 108, 108, 111])
s = b.decode('utf-8')  # 输出: 'Hello'

请注意,编码和解码时使用的编码方式(如'utf-8')必须匹配,否则可能会出现错误或不可预测的结果。

2.6.3 可变字节数组

在Python中,bytearray 是一个可变的字节序列。与 bytes 类型类似,bytearray 用于表示字节数据,但不同于 bytes 的是,bytearray 是可变的,可以在原地进行修改。

bytearray 对象的常用于需要频繁修改字节数据的场景,或者需要一个可以直接修改的字节缓冲区的场景。

下面为bytearray的创建、增加、删除、修改及其他操作示例:

# 定义可变字节数组
ba = bytearray([65, 66, 67])  # 相当于ASCII字符 'A', 'B', 'C'
print(ba)  # 输出: bytearray(b'ABC')

# bytearray 从 bytes 对象转换
b = b'Hello'
ba = bytearray(b)
print(ba)  # 输出: bytearray(b'Hello')

# 从字符串和编码转换
s = 'Hello'
ba = bytearray(s, 'utf-8')
print(ba)  # 输出: bytearray(b'Hello')

# bytearray 转换为 bytes
ba = bytearray([72, 101, 108, 108, 111])
b = ba.tobytes()  
print(b)   # 输出: b'Hello'

# bytearray的值
ba = bytearray(b'Hello')
print(ba[0])  # 输出: 72(ASCII码中'H'的值)
print(ba[1:4])  # 输出: bytearray(b'ell')

# 将第一个字节改为'B'的ASCII码
ba[0] = 66  
print(ba)  # 输出: bytearray(b'Bello')

# 添加元素
ba.append(111)  # 添加ASCII码为111的字符'o'
print(ba)  # 输出: bytearray(b'Belloo')

# 插入元素
ba.insert(1, 97)  # 在索引1的位置插入ASCII码为97的字符'a'
print(ba)  # 输出: bytearray(b'Baelloo')

# 删除索引1的元素
del ba[1]  
print(ba)  # 输出: bytearray(b'Belloo')
 
# 或者使用pop方法,这会返回被删除的元素
removed_byte = ba.pop(1)
print(ba)  # 输出: bytearray(b'Bloo')
print(removed_byte)  # 输出: 101(ASCII码中'e'的值)

# 扩展 bytearray
ba.extend(bytearray([103, 111]))  # 添加ASCII码为103和111的字符'g'和'o'
print(ba)  # 输出: bytearray(b'Blogo')

2.6.4 可变字节数组的编码和解码

虽然 bytearray 通常用于处理已经编码的字节数据,但它也可以像 bytes 一样进行解码。例如:

ba = bytearray(b'Hello')
s = ba.decode('utf-8')  # 解码为字符串
print(s)  # 输出: 'Hello'

但是,由于 bytearray 是可变的,你通常不会用它来进行编码,除非你需要一个可修改的字节缓冲区,并在之后将其转换为 bytes。

2.7 特殊类型

Python 提供了多种内置的数据类型,其中一些可以被视为“特殊”类型(这个术语并不是 Python 官方文档中的正式用语)。

以下是一些通常被认为是“特殊”的 Python 类型:

  • NoneType(空类型): None
  • type(类型): 用于获取对象类型
  • ellipsis(省略号): 通常用 … 表示,用于在切片中表示省略或占位
  • NotImplemented(未实现): 通常在运算符重载时用于表示不支持某个操作

特殊类型示例:

# None
none_var = None
print(none_var, type(none_var))  # 输出: None <class 'NoneType'>

# 类型
type_var = type(123)
print(type_var, type(type_var))  # 输出: <class 'int'> <class 'type'>

# 省略号
ellipsis_var = ...
print(ellipsis_var, type(ellipsis_var))  # 输出: Ellipsis <class 'ellipsis'>

# 未实现
def my_unsupported_op():
    return NotImplemented

print(my_unsupported_op(), type(NotImplemented))  # 输出: NotImplemented <class 'NotImplementedType'>

2.8 自定义类型

# 通过类定义自定义类型
class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

person_obj = Person("Bob", 25)
print(person_obj, type(person_obj))  # 输出: <__main__.Person object at 0x...> <class '__main__.Person'>

请注意,<__main__.Person object at 0x...> 中的0x... 是对象在内存中的地址的十六进制表示,这个地址每次运行都可能不同。在上面的自定义类型示例中,我们定义了一个名为 Person 的类,并创建了一个该类的实例 person_obj。然后,我们打印了这个对象以及它的类型。

注:自定义类型(类)是面向对象编程(OOP)的核心概念之一,它允许你创建具有属性和方法的复杂数据结构,并通过这些方法来操作这些数据。我们将在类于对象中做更加详尽的介绍。