数据类型#
Python 中的数据类型可以分为两大类:基本数据类型和容器类型。理解这些数据类型是掌握 Python 的基础。
数字类型#
整数(int)#
整数可以是正数、负数或零,没有大小限制(Python 3)。
# 整数
x = 10
y = -5
z = 0
# 大整数
big_number = 123456789012345678901234567890
# 不同进制的整数
binary = 0b1010 # 二进制,结果是 10
octal = 0o12 # 八进制,结果是 10
hexadecimal = 0xA # 十六进制,结果是 10浮点数(float)#
浮点数表示带小数点的数字。
# 浮点数
x = 3.14
y = -0.5
z = 2.0
# 科学计数法
scientific = 1.5e2 # 1.5 × 10² = 150.0
small = 1e-3 # 1 × 10⁻³ = 0.001
# 注意浮点数精度问题
result = 0.1 + 0.2
print(result) # 0.30000000000000004(浮点数精度问题)复数(complex)#
复数由实部和虚部组成。
# 复数
z1 = 3 + 4j
z2 = complex(3, 4) # 等价于 3 + 4j
# 访问实部和虚部
print(z1.real) # 3.0
print(z1.imag) # 4.0数字类型转换#
# int() - 转换为整数
x = int(3.7) # 3(向下取整)
x = int("10") # 10
# float() - 转换为浮点数
y = float(10) # 10.0
y = float("3.14") # 3.14
# complex() - 转换为复数
z = complex(3, 4) # (3+4j)布尔类型(bool)#
布尔类型只有两个值:True 和 False(注意首字母大写)。
# 布尔值
is_valid = True
is_empty = False
# 布尔转换
bool(1) # True
bool(0) # False
bool("") # False(空字符串)
bool("abc") # True(非空字符串)
bool([]) # False(空列表)
bool([1, 2]) # True(非空列表)
# 布尔运算
True and False # False
True or False # True
not True # False字符串(str)#
字符串是 Python 中最常用的数据类型之一,用单引号、双引号或三引号包围。
字符串创建#
# 单引号
s1 = 'Hello'
# 双引号
s2 = "World"
# 三引号(可以跨越多行)
s3 = """这是
多行
字符串"""
# 转义字符
s4 = "他说:\"你好\"" # 他说:"你好"
s5 = "第一行\n第二行" # 换行
s6 = "制表符\t分隔" # 制表符字符串索引和切片#
s = "Python"
# 索引(从0开始)
s[0] # 'P'
s[1] # 'y'
s[-1] # 'n'(最后一个字符)
s[-2] # 'o'(倒数第二个)
# 切片 [start:end:step]
s[0:3] # 'Pyt'(索引0到2)
s[:3] # 'Pyt'(从开始到索引2)
s[3:] # 'hon'(从索引3到结尾)
s[::2] # 'Pto'(每隔一个字符)
s[::-1] # 'nohtyP'(反转字符串)字符串格式化#
字符串格式化是将变量、表达式或值插入到字符串模板中,控制数字的小数位数、对齐方式、填充字符等
方法一:f-string(Python 3.6+,推荐)
name = "Python"
age = 30
print(f"我是{name},今年{age}岁")
# 表达式
x = 10
print(f"x的平方是{x**2}")
# 格式化数字
pi = 3.14159
print(f"π的值是{pi:.2f}") # 保留2位小数方法二:format() 方法
name = "Python"
age = 30
print("我是{},今年{}岁".format(name, age))
print("我是{0},今年{1}岁".format(name, age))
print("我是{name},今年{age}岁".format(name=name, age=age))方法三:% 格式化(旧式,不推荐)
name = "Python"
age = 30
print("我是%s,今年%d岁" % (name, age))字符串常用方法#
s = " Hello World "
# 大小写转换
s.upper() # ' HELLO WORLD '
s.lower() # ' hello world '
s.title() # ' Hello World '
s.capitalize() # ' hello world '
# 去除空白
s.strip() # 'Hello World'(去除两端空白)
s.lstrip() # 'Hello World '(去除左端空白)
s.rstrip() # ' Hello World'(去除右端空白)
# 查找和替换
s.find("World") # 7(返回索引,找不到返回-1)
s.index("World") # 7(返回索引,找不到抛出异常)
s.replace("World", "Python") # ' Hello Python '
# 分割和连接
"a,b,c".split(",") # ['a', 'b', 'c']
",".join(['a', 'b', 'c']) # 'a,b,c'
# 检查
s.startswith("Hello") # False
s.endswith("World") # False
s.isdigit() # False
s.isalpha() # False
"123".isdigit() # True
# 计数
"hello".count("l") # 2
len("hello") # 5(内置函数)列表(list)#
列表是有序的可变序列,用方括号 [] 表示。
列表创建#
# 创建列表
list1 = [1, 2, 3]
list2 = ["a", "b", "c"]
list3 = [1, "hello", 3.14, True] # 可以包含不同类型
list4 = [] # 空列表
list5 = list(range(5)) # [0, 1, 2, 3, 4]列表索引和切片#
my_list = [10, 20, 30, 40, 50]
# 索引
my_list[0] # 10
my_list[-1] # 50(最后一个元素)
# 切片
my_list[1:3] # [20, 30]
my_list[:3] # [10, 20, 30]
my_list[2:] # [30, 40, 50]
my_list[::2] # [10, 30, 50](每隔一个)
my_list[::-1] # [50, 40, 30, 20, 10](反转)列表操作#
my_list = [1, 2, 3]
# 添加元素
my_list.append(4) # [1, 2, 3, 4]
my_list.insert(1, 10) # [1, 10, 2, 3, 4](在索引1处插入)
my_list.extend([5, 6]) # [1, 10, 2, 3, 4, 5, 6]
# 删除元素
my_list.remove(10) # 删除第一个值为10的元素
del my_list[0] # 删除索引0的元素
popped = my_list.pop() # 删除并返回最后一个元素
popped = my_list.pop(1) # 删除并返回索引1的元素
# 查找
my_list.index(3) # 返回第一个值为3的索引
my_list.count(3) # 统计值为3的元素个数
# 排序
my_list.sort() # 原地排序
sorted_list = sorted(my_list) # 返回新列表
my_list.reverse() # 原地反转
# 其他
len(my_list) # 列表长度
3 in my_list # 检查元素是否存在列表推导式#
列表推导式是创建列表的简洁方法:
# 基本语法:[表达式 for 变量 in 可迭代对象]
squares = [x**2 for x in range(5)] # [0, 1, 4, 9, 16]
# 带条件
evens = [x for x in range(10) if x % 2 == 0] # [0, 2, 4, 6, 8]
# 嵌套循环
matrix = [[i*j for j in range(3)] for i in range(3)]
# [[0, 0, 0], [0, 1, 2], [0, 2, 4]]元组(tuple)#
元组是有序的不可变序列,用圆括号 () 表示。
# 创建元组
t1 = (1, 2, 3)
t2 = ("a", "b", "c")
t3 = 1, 2, 3 # 括号可以省略
t4 = (1,) # 单元素元组需要逗号
t5 = () # 空元组
# 索引和切片(与列表相同)
t = (10, 20, 30)
t[0] # 10
t[1:3] # (20, 30)
# 元组是不可变的
# t[0] = 100 # 错误!不能修改元组
# 元组解包
x, y, z = (1, 2, 3)
x, y = y, x # 交换变量值
# 元组方法
t.count(10) # 统计元素个数
t.index(20) # 返回索引字典(dict)#
字典是键值对的无序集合,用花括号 {} 表示。
字典创建#
# 创建字典
dict1 = {"name": "Python", "age": 30}
dict2 = dict(name="Python", age=30)
dict3 = dict([("name", "Python"), ("age", 30)])
dict4 = {} # 空字典
# 访问元素
dict1["name"] # 'Python'
dict1.get("name") # 'Python'(推荐,不会报错)
dict1.get("city", "未知") # '未知'(如果键不存在返回默认值)字典操作#
my_dict = {"name": "Python", "age": 30}
# 添加/修改
my_dict["city"] = "Beijing"
my_dict["age"] = 31
# 删除
del my_dict["city"]
value = my_dict.pop("age") # 删除并返回值
my_dict.clear() # 清空字典
# 遍历
for key in my_dict:
print(key, my_dict[key])
for key, value in my_dict.items():
print(key, value)
for value in my_dict.values():
print(value)
# 检查
"name" in my_dict # True
len(my_dict) # 字典长度字典推导式#
# 基本语法:{键表达式: 值表达式 for 变量 in 可迭代对象}
squares = {x: x**2 for x in range(5)} # {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
# 带条件
evens = {x: x**2 for x in range(10) if x % 2 == 0}集合(set)#
集合是无序的不重复元素集合,用花括号 {} 表示(注意:空集合用 set() 创建)。
集合创建#
# 创建集合
set1 = {1, 2, 3}
set2 = set([1, 2, 3, 3]) # {1, 2, 3}(自动去重)
set3 = set() # 空集合(不能用{},那是空字典)
# 集合会自动去重
my_set = {1, 2, 2, 3, 3} # {1, 2, 3}集合操作#
set1 = {1, 2, 3, 4}
set2 = {3, 4, 5, 6}
# 添加和删除
set1.add(5) # {1, 2, 3, 4, 5}
set1.remove(5) # {1, 2, 3, 4}(元素不存在会报错)
set1.discard(5) # {1, 2, 3, 4}(元素不存在不报错)
set1.pop() # 删除并返回任意元素
# 集合运算
set1 | set2 # 并集:{1, 2, 3, 4, 5, 6}
set1 & set2 # 交集:{3, 4}
set1 - set2 # 差集:{1, 2}
set1 ^ set2 # 对称差集:{1, 2, 5, 6}
# 集合方法
set1.union(set2) # 并集
set1.intersection(set2) # 交集
set1.difference(set2) # 差集
set1.symmetric_difference(set2) # 对称差集
# 检查
3 in set1 # True
set1.issubset(set2) # False
set1.issuperset(set2) # False集合推导式#
# 基本语法:{表达式 for 变量 in 可迭代对象}
squares = {x**2 for x in range(5)} # {0, 1, 4, 9, 16}
# 带条件
evens = {x for x in range(10) if x % 2 == 0} # {0, 2, 4, 6, 8}类型转换#
# 转换为字符串
str(123) # '123'
str(3.14) # '3.14'
# 转换为数字
int("123") # 123
int(3.7) # 3
float("3.14") # 3.14
# 转换为列表
list("abc") # ['a', 'b', 'c']
list((1, 2, 3)) # [1, 2, 3]
# 转换为元组
tuple([1, 2, 3]) # (1, 2, 3)
# 转换为集合
set([1, 2, 2, 3]) # {1, 2, 3}
# 转换为字典(需要可迭代的键值对)
dict([("a", 1), ("b", 2)]) # {'a': 1, 'b': 2}可变与不可变对象(重点难点)#
这是 Python 中非常重要的概念,理解它有助于避免很多常见的错误。
不可变对象(Immutable)#
不可变对象一旦创建就不能修改。如果"修改"它们,实际上是创建了新的对象。
不可变类型:
- 数字(int, float, complex)
- 字符串(str)
- 元组(tuple)
- 布尔值(bool)
- frozenset(不可变集合)
# 字符串是不可变的
s = "hello"
s[0] = "H" # 错误!不能修改字符串
# 实际上创建了新对象
s = "hello"
id(s) # 某个内存地址
s = s + "!" # 创建了新字符串对象
id(s) # 不同的内存地址
# 元组是不可变的
t = (1, 2, 3)
# t[0] = 10 # 错误!不能修改元组可变对象(Mutable)#
可变对象可以在创建后修改。
可变类型:
- 列表(list)
- 字典(dict)
- 集合(set)
# 列表是可变的
my_list = [1, 2, 3]
my_list[0] = 10 # 可以修改
my_list.append(4) # 可以添加元素
# 字典是可变的
my_dict = {"a": 1}
my_dict["b"] = 2 # 可以添加
my_dict["a"] = 10 # 可以修改可变对象作为函数参数#
重要:当可变对象作为函数参数时,函数内部对对象的修改会影响原对象!
def modify_list(lst):
lst.append(4) # 修改列表
lst[0] = 100 # 修改列表
my_list = [1, 2, 3]
modify_list(my_list)
print(my_list) # [100, 2, 3, 4](原列表被修改了!)
# 如果不想修改原列表,可以传入副本
def modify_list_safe(lst):
lst = lst.copy() # 创建副本
lst.append(4)
return lst
my_list = [1, 2, 3]
new_list = modify_list_safe(my_list)
print(my_list) # [1, 2, 3](原列表未改变)
print(new_list) # [1, 2, 3, 4]不可变对象作为函数参数#
def modify_string(s):
s = s + "!" # 创建新字符串,不影响原字符串
my_string = "hello"
modify_string(my_string)
print(my_string) # "hello"(原字符串未改变)浅拷贝与深拷贝#
import copy
# 浅拷贝(shallow copy)
list1 = [[1, 2], [3, 4]]
list2 = list1.copy() # 或 list2 = list1[:]
list2[0][0] = 100
print(list1) # [[100, 2], [3, 4]](嵌套列表也被修改了!)
# 深拷贝(deep copy)
list1 = [[1, 2], [3, 4]]
list2 = copy.deepcopy(list1)
list2[0][0] = 100
print(list1) # [[1, 2], [3, 4]](原列表未改变)类型检查#
# type() - 获取类型
type(10) # <class 'int'>
type("hello") # <class 'str'>
# isinstance() - 检查类型(推荐)
isinstance(10, int) # True
isinstance("hello", str) # True
isinstance([1, 2], (list, tuple)) # True(检查多个类型)下一步#
掌握了数据类型后,可以学习: