列表与元组
创建与访问
总结
- 列表的创建:可以通过
[]
或list()
来创建列表,它们都属于 Python 的内建数据类型list
- 访问与修改元素:通过索引可以访问和修改列表中的元素,支持正向和负向索引。正向索引从 0 开始,而负向索引从 -1 开始,表示列表的最后一个元素
- 列表的长度:可以使用
len(a)
来获取列表的元素数量 - 列表元素的多样性:列表可以包含不同类型的元素,包括整数、字符串、布尔值、嵌套列表等
# 创建一个空列表,使用的是字面量 [] 来定义
a = []
# 打印 a 的类型,输出应该是 <class 'list'>
print(type(a))
# 创建一个空列表,使用 list() 函数来定义
b = list()
# 打印 b 的类型,输出也应该是 <class 'list'>
print(type(b))
# 创建一个包含整数的列表
a = [1, 2, 3, 4]
# 打印列表 a
print(a)
# 打印列表 a 中索引为 2 的元素,输出是 3,因为索引从 0 开始
print(a[2])
# 修改列表 a 中索引为 2 的元素的值,将其修改为 1000
a[2] = 1000
# 打印修改后的 a[2],输出应为 1000
print(a[2])
# 打印修改后的整个列表 a,应该是 [1, 2, 1000, 4]
print(a)
# 如果我们尝试访问索引为 4 的元素,代码会引发 IndexError 错误,因为 a 只包含 4 个元素(索引从 0 到 3)
# print(a[4]) # 这行代码被注释掉了
# 使用 len(a)-1 来访问列表 a 的最后一个元素
print(a[len(a)-1])
# 通过负索引 -1 直接访问列表 a 的最后一个元素
print(a[-1])
# 创建一个包含多种数据类型的列表
a = [1, 'h', "hello", True, [666, 888]]
# 打印包含不同数据类型的列表 a
print(a)
# 打印列表 a 的长度,应该输出 5,因为 a 中有 5 个元素
print(len(a))
切片
总结
- 切片语法 切片操作
a[start:end:step]
用于从列表a
中提取一个子列表start
是起始索引(包括该索引位置)end
是结束索引(不包括该索引位置)step
是步长,决定了每次移动多少个位置
- 如果省略某个部分
start
默认为 0(从列表的第一个元素开始)end
默认为列表的末尾step
默认为 1(连续提取元素)
# 创建一个包含整数的列表 a
a = [1, 2, 3, 4]
# 使用切片操作访问 a 的一部分。a[1:3] 会返回索引从 1 到 2(不包括 3)之间的元素,结果是 [2, 3]
print(a[1:3])
# 使用切片操作访问 a 中索引从 1 到结束的部分,结果是 [2, 3, 4]
print(a[1:])
# 使用切片操作访问 a 中从开始到索引 2(不包括 3)之间的部分,结果是 [1, 2, 3]
print(a[:3])
# 使用负索引访问 a 中最后一个元素的部分,结果是 [4](切片语法会返回列表,即使只有一个元素)
print(a[-1:])
# 使用切片操作访问 a 中从开始到倒数第二个元素的部分,结果是 [1, 2, 3]
print(a[:-1])
# 使用切片操作访问整个列表,结果是 [1, 2, 3, 4]
print(a[:])
# 创建一个包含整数的列表 a,长度为 9
a = [1, 2, 3, 4, 5, 6, 7, 8, 9]
# 使用切片操作访问整个列表,步长为 1,等同于 a[::1],结果是 [1, 2, 3, 4, 5, 6, 7, 8, 9]
print(a[::1])
# 使用切片操作访问列表中的元素,步长为 2,结果是 [1, 3, 5, 7, 9]
print(a[::2])
# 使用切片操作访问列表中的元素,步长为 3,结果是 [1, 4, 7]
print(a[::3])
# 使用切片操作访问列表中从索引 1 到倒数第一个元素之间,步长为 2,结果是 [2, 4, 6, 8]
print(a[1:-1:2])
# 使用负步长切片操作反转列表,结果是 [9, 8, 7, 6, 5, 4, 3, 2, 1]
print(a[::-1])
# 使用负步长切片操作反转列表,并跳过一个元素,结果是 [9, 7, 5, 3, 1]
print(a[::-2])
# 使用切片操作访问从索引 1 到索引 100 之间的元素,由于索引超出范围,Python 会返回索引范围内的元素 [2, 3, 4, 5, 6, 7, 8, 9]
print(a[1:100])
遍历
总结
遍历列表
- 使用
for
循环和in
语法可以简洁地遍历列表中的每个元素 - 使用
range()
和for
循环可以通过索引访问列表元素,适合需要修改元素值的情况 while
循环也可以遍历列表,但需要手动控制索引的更新
使用 range()
生成索引序列
range(0, len(a))
用于生成一个从 0 到len(a)-1
的序列,适合在for
循环中访问列表的索引
# 创建一个包含整数的列表 a
a = [1, 2, 3, 4, 5, 6, 7, 8, 9]
# 使用 for 循环遍历列表 a,逐个打印列表中的元素
for elem in a:
print(elem)
# 使用 range 和 for 循环遍历列表 a,逐个访问并修改列表中的元素
# 这里我们使用 range(0, len(a)) 来生成从 0 到 len(a)-1 的索引
for i in range(0, len(a)):
a[i] = a[i] + 10 # 每个元素加 10
# 打印修改后的列表 a
print(a)
# 使用 while 循环遍历列表 a,逐个打印列表中的元素
# 通过 while 循环控制索引 i 的增加
i = 0
while i < len(a):
print(a[i])
i += 1 # 每次循环后,i 自增 1
新增元素
总结
- append()
- 将一个元素放到列表的末尾,操作可以直接修改列表
- insert()
- 用于在指定的索引位置插入元素,元素插入时,列表中原来该位置的元素及其后续元素会向后移动
- 如果插入的index大于当前列表的长度,那么会将元素直接添加到列表的末尾
# 创建一个包含整数的列表 a
a = [1, 2, 3, 4]
# 使用 append() 方法在列表末尾添加一个元素 5
a.append(5)
# 使用 append() 方法在列表末尾添加一个字符串 "hello"
a.append("hello")
# 打印修改后的列表 a,输出 [1, 2, 3, 4, 5, 'hello']
print(a)
# 使用 insert() 方法在索引 1 的位置插入一个元素 "world"
# insert(index, element) 会将 element 插入到列表中的 index 位置,现有元素会向后移动
a.insert(1, "world")
# 打印修改后的列表 a,输出 [1, 'world', 2, 3, 4, 5, 'hello']
print(a)
# 使用 insert() 方法尝试在索引 100 处插入一个元素 "ggm"
# 由于索引 100 超出了当前列表的范围,insert() 会将 "ggm" 添加到列表末尾
a.insert(100, "ggm")
# 打印修改后的列表 a,输出 [1, 'world', 2, 3, 4, 5, 'hello', 'ggm']
print(a)
查找与删除元素
总结
-
in
和not in
操作符in
用于检查元素是否在列表中,返回True
或False
not in
用于检查元素是否不在列表中,返回True
或False
-
index()
方法index()
返回指定元素在列表中的索引位置。如果元素不存在,会引发ValueError
错误
-
pop()
方法pop()
用于删除并返回列表中的一个元素。如果没有指定索引,默认删除最后一个元素- 如果提供了索引,
pop(index)
会删除指定索引位置的元素,并返回该元素
-
remove()
方法remove()
用于删除列表中的第一个匹配的元素。如果元素在列表中不存在,会引发ValueError
错误- 与
pop()
不同,remove()
根据值删除元素,而不是根据索引
# 创建一个包含整数的列表 a
a = [1, 2, 3, 4]
# 检查元素 1 是否在列表 a 中,输出结果为 True,因为 1 存在于列表 a 中
print(1 in a)
# 检查元素 10 是否在列表 a 中,输出结果为 False,因为 10 不在列表 a 中
print(10 in a)
# 检查元素 1 是否不在列表 a 中,输出结果为 False,因为 1 在列表 a 中
print(1 not in a)
# 检查元素 5 是否不在列表 a 中,输出结果为 True,因为 5 不在列表 a 中
print(5 not in a)
# 获取列表 a 中第一个出现的元素 2 的索引位置,输出结果为 1(索引从 0 开始)
print(a.index(2))
# 如果尝试查找不存在的元素 5 的索引,会引发 ValueError 错误
# print(a.index(5)) # 这行代码被注释掉了,避免运行时错误
# 打印列表 a,输出 [1, 2, 3, 4]
print(a)
# 使用 pop() 方法删除列表中的最后一个元素(默认行为),并返回该元素,删除的是 4
a.pop()
# 打印删除后的列表,输出 [1, 2, 3]
print(a)
# 使用 pop(1) 删除索引位置 1 的元素,即删除元素 2
a.pop(1)
# 打印删除后的列表,输出 [1, 3]
print(a)
# 创建一个包含字符串的列表 b
b = ['aa', 'bb', 'cc']
# 使用 remove() 方法删除列表中的元素 'cc',如果列表中存在该元素,会删除第一个匹配的元素
b.remove('cc')
# 打印删除后的列表,输出 ['aa', 'bb']
print(b)
连接列表
总结
-
+
运算符会创建一个新的列表,适用于需要合并并返回一个新列表的场景,但要注意它会创建新的内存空间,可能相对较慢 extend()
和+=
操作是在原列表上进行修改,性能更优,因为它们不会创建新的列表对象,而是直接在原列表上添加元素
# 创建两个列表 a 和 b
a = [1, 2, 3, 4]
b = [5, 6, 7, 8]
# 使用加法运算符 + 连接两个列表 a 和 b,创建一个新的列表 c
# c 是列表 a 和 b 的元素合并,结果是 [1, 2, 3, 4, 5, 6, 7, 8]
c = a + b
# 打印新列表 c
print(c)
# 使用 extend() 方法将列表 b 中的元素添加到列表 a 的末尾
# 注意:extend() 是修改原始列表 a 的,而不是创建新的列表
# 结果是列表 a 变为 [1, 2, 3, 4, 5, 6, 7, 8]
a.extend(b)
# 打印修改后的列表 a
print(a)
# 打印列表 b,b 没有改变,仍然是 [5, 6, 7, 8]
print(b)
# 使用 += 运算符将列表 b 中的元素添加到列表 a 的末尾
# += 运算符与 extend() 方法类似,都会修改原列表 a
a += b
# 打印修改后的列表 a,结果是 [1, 2, 3, 4, 5, 6, 7, 8, 5, 6, 7, 8]
print(a)
# 打印列表 b,b 仍然没有改变,仍然是 [5, 6, 7, 8]
print(b)
元组
总结
-
元组的定义与创建
- 元组通过小括号
()
创建,也可以使用tuple()
构造函数。元组是不可变类型,一旦创建就不能修改
- 元组通过小括号
-
元组的不可变性
- 元组一旦创建后,它的内容不能被修改(不能添加、删除或修改元素)。这与列表不同,列表是可变的
-
访问元组元素
- 元组支持通过索引和切片来访问元素。索引从 0 开始,切片支持获取元组的子集
-
in
和index()
方法in
用于检查元素是否在元组中,而index()
用于返回元素在元组中的索引位置。若元素不存在,index()
会抛出ValueError
-
遍历元组
- 可以使用
for
循环遍历元组,逐个访问其中的元素
- 可以使用
-
+
运算符- 使用
+
运算符可以连接两个元组,返回一个新的元组,原元组不变
- 使用
# 创建一个空的元组 a
a = ()
# 打印 a 的类型,输出 <class 'tuple'>,表示 a 是一个元组
print(type(a))
# 创建一个空的元组 b
b = tuple()
# 打印 b 的类型,输出 <class 'tuple'>,表示 b 是一个元组
print(type(b))
# 创建一个包含整数的元组 b
b = (1, 2, 3, 4)
# 打印元组 b,输出 (1, 2, 3, 4)
print(b)
# 打印元组 b 中索引为 1 的元素,输出 2
print(b[1])
# 打印元组 b 中索引为 2 的元素,输出 3
print(b[2])
# 使用切片操作,打印元组 b 中索引 1 到 3(不包括 3)之间的元素,输出 (2, 3)
print(b[1:3])
# 打印元组 b 的所有元素,使用默认步长,输出 (1, 2, 3, 4)
print(b[::])
# 创建一个包含不同类型元素的元组 c
c = (1, 2, "hello", True, [2333, 4555])
# 打印元组 c,输出 (1, 2, 'hello', True, [2333, 4555])
print(c)
# 创建一个包含整数的元组 d
d = (1, 2, 3, 45)
# 使用 for 循环遍历元组 d,逐个打印其中的元素
for elem in d:
print(elem)
# 创建一个包含整数的元组 e
e = (1, 2, 3, 4)
# 检查元素 3 是否在元组 a 中,输出 False,因为元组 a 为空
print(3 in a)
# 使用 index() 方法查找元素 1 在元组 e 中的索引位置,输出 0(索引从 0 开始)
print(e.index(1))
# 尝试修改元组 e 中的第一个元素,元组是不可变的,所以这行代码会抛出 TypeError 错误
# e[0] = 100 # 这一行代码被注释掉了,避免抛出异常
# 使用 + 运算符连接元组 d 和 e,返回一个新的元组,输出 (1, 2, 3, 45, 1, 2, 3, 4)
print(d + e)
字典
创建字典
总结
-
键值对的规则:
- 键必须是不可变的(如字符串、数字、元组),且键是唯一的
- 值可以是任意类型(如字符串、数字、列表、字典等)
-
创建字典的常用方式:
- 使用
{}
直接创建字典(常用) - 使用
dict()
构造函数(灵活) - 通过字典推导式动态生成
- 从键值对的列表或元组创建
- 使用
-
创建空字典:
- 使用
{}
或dict()
- 使用
-
适用场景:
- 静态字典:
{}
定义初始内容 - 动态字典: 使用空字典
dict()
并逐步添加键值对 - 复杂字典: 从其他数据结构(如列表、元组)生成
- 静态字典:
# 创建一个字典 a,使用字典字面量 {},包含两个键值对:'id': 1 和 'name': '猪粑粑'
a = {'id': 1, 'name': '猪粑粑'}
# 打印 a 的类型,输出 <class 'dict'>,表示 a 是一个字典
print(type(a))
# 打印字典 a 的内容,输出 {'id': 1, 'name': '猪粑粑'}
print(a)
# 创建一个空字典 b,使用 dict() 构造函数
b = dict()
# 打印 b 的类型,输出 <class 'dict'>,表示 b 是一个字典
print(type(b))
# 创建一个字典 d,使用 dict() 构造函数并传递键值对参数
# 键值对通过 key=value 的形式传递(键必须是字符串类型)
d = dict(key1="v1", key2="v2")
# 打印字典 d,输出 {'key1': 'v1', 'key2': 'v2'}
print(d)
# 创建一个字典 e,使用 dict() 构造函数并传递一个由元组组成的列表
# 每个元组表示一个键值对,键和值可以是任意类型
e = dict([("key1", "value1"), ("key2", "value2")])
# 打印字典 e,输出 {'key1': 'value1', 'key2': 'value2'}
print(e)
查找Key
总结
- 检查键是否存在:
- 使用
in
和not in
检查键是否存在或不存在
- 使用
- 访问值:
- 使用键访问值,格式为:
字典[键]
- 使用键访问值,格式为:
- 注意 KeyError:
- 在访问字典中不存在的键时会报
KeyError
,可以通过get()
方法设置默认值来避免
- 在访问字典中不存在的键时会报
# 创建一个字典 a,包含两个键值对:'id': 1 和 'name': '小钱'
a = {
'id': 1,
'name': '小钱'
}
# 使用 `in` 操作符检查字典 a 中是否存在键 'id',结果为 True,因为字典中有这个键
print('id' in a)
# 使用 `in` 操作符检查字典 a 中是否存在键 'class',结果为 False,因为字典中没有这个键
print('class' in a)
# 使用 `in` 操作符检查字典 a 中是否存在值 "小钱",结果为 False,因为 `in` 只检查字典的键,不会检查值
print("小钱" in a)
# 使用 `not in` 操作符检查字典 a 中是否不存在键 'class',结果为 True,因为字典中没有这个键
print('class' not in a)
# 创建另一个字典 b,包含两个键值对:'id': 1 和 'name': 'xiaowang'
b = {
'id': 1,
'name': 'xiaowang'
}
# 使用键访问字典 b 中的值,打印键 'id' 对应的值,结果为 1
print(b['id'])
# 使用键访问字典 b 中的值,打印键 'name' 对应的值,结果为 'xiaowang'
print(b['name'])
# 尝试访问字典中不存在的键 '100',会引发 KeyError 错误(这一行代码被注释掉了,避免运行时报错)
# print(a[100]) # KeyError: 100
c = dict([("name", "小明"), ("age", 25), ("city", "北京"), ("hobby", "足球")])
for key,value in c.items():
print(f"{key}:{value}")
del c['name']
print(c
新增修改与删除
总结
- 动态添加键值对: 使用
字典[键] = 值
- 修改字典中的值: 如果键已存在,赋值操作会覆盖原值
- 删除键值对: 使用
pop(键)
删除指定的键及其对应值 - 字典的可变性: 字典支持动态修改(添加、更新和删除),可以灵活调整内容
- 常用方法:
pop()
:删除指定键get()
:安全获取键的值in
:判断键是否存在
# 创建一个字典 a,包含两个键值对:'id': 1 和 'name': 'xiaomign'
a = {
'id': 1,
'name': 'xiaomign'
}
# 打印字典 a,输出 {'id': 1, 'name': 'xiaomign'}
print(a)
# 向字典 a 中添加一个新的键值对 'score': 100
a['score'] = 100
# 打印字典 a,输出 {'id': 1, 'name': 'xiaomign', 'score': 100}
print(a)
# 修改字典中已有键 'score' 的值,将其从 100 修改为 99
a['score'] = 99
# 打印字典 a,输出 {'id': 1, 'name': 'xiaomign', 'score': 99}
print(a)
# 删除字典中的键 'name' 及其对应的值
a.pop('name')
# 打印字典 a,输出 {'id': 1, 'score': 99}
print(a)
遍历字典
总结
- 遍历键:for key in a
- 遍历键值对:for key , value in a.items()
- 获取字典视图对象
- key():返回所有键
- values():返回所有值
- items():返回所有键值
# 定义一个字典 a,包含三个键值对:'id': 1, 'name': 'xiaomign', 'score': 90
a = {
'id': 1,
'name': 'xiaomign',
'score': 90
}
# 遍历字典的键,通过键访问对应的值
# 遍历字典 a 中的每个键,打印键和值
for key in a:
print(key, a[key]) # 输出键和值,格式为:键 值
# 打印字典的所有键
# a.keys() 方法返回字典中所有的键,结果是一个字典视图对象
print(a.keys()) # 输出:dict_keys(['id', 'name', 'score'])
# 打印字典的所有值
# a.values() 方法返回字典中所有的值,结果是一个字典视图对象
print(a.values()) # 输出:dict_values([1, 'xiaomign', 90])
# 打印字典的所有键值对
# a.items() 方法返回字典中的所有键值对,结果是一个字典视图对象,每个元素是一个元组 (key, value)
print(a.items()) # 输出:dict_items([('id', 1), ('name', 'xiaomign'), ('score', 90)])
# 使用 a.items() 遍历字典的键值对
# for 循环同时解包键和值,分别赋值给变量 key 和 value
for key, value in a.items():
print(key, value) # 输出格式为:键 值
合法key的类型
总结
def is_hashable(obj):
try:
hash(obj)
return True
except TypeError:
return False
# 示例:
print(is_hashable(42)) # True
print(is_hashable("hello")) # True
print(is_hashable([1, 2, 3])) # False
print(is_hashable((1, 2, 3))) # True
print(is_hashable({"a": 1})) # False