AI项目博客
记录 AI 工程实践与大模型应用

Python 学习笔记 13|序列的切片操作

5. 序列的切片操作

5.1. 概述

何为序列?—— 能连续存放元素的数据容器,而且元素有先后顺序,而且可以通过下标访问,所以我们学过的:列表、元组、字符串,都是序列。

何为切片?—— 从序列中按照指定范围,取出一部分元素,形成一个新的序列的操作。

5.2. 基本语法

语法格式为:序列[起始索引:结束索引:步长]

相关注意点如下:

  • 切片操作的区间是左闭右开的,即:截取时包含起始位置,但不包含结束位置。
  • 步长是指取出元素时的间隔,例如:
  • 步长为 1,就是一个一个取出。
  • 步长为 2,就是每次越过 1 个元素取出。
  • 步长为 3,就是每次越过 2 个元素取出。
  • 步长为 n,就是每次越过 n-1 个元素取出。
  • 起始索引默认值为 0,结束索引默认截取到末尾,步长默认值为 1。
  • 当起始索引大于结束索引时,步长必须为负数,否则结果是空列表。

测试代码:

# 对列表进行切片
list1 = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100]
list2 = list1[0:5:1]
print(list2)  # [10, 20, 30, 40, 50]

list1 = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100]
list2 = list1[1:8:2]
print(list2)  # [20, 40, 60, 80]

list1 = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100]
list2 = list1[1:8:3]
print(list2)  # [20, 40, 60, 80]

list1 = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100]
list2 = list1[::]  # [10, 20, 30, 40, 50, 60, 70, 80, 90, 100]
print(list2)

list1 = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100]
list2 = list1[:999:] 
print(list2) # [10, 20, 30, 40, 50, 60, 70, 80, 90, 100]

list1 = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100]
list2 = list1[3::]  
print(list2)  # [40, 50, 60, 70, 80, 90, 100]

list1 = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100]
list2 = list1[:5:]
print(list2)  # [10, 20, 30, 40, 50]

list1 = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100]
list2 = list1[::4]
print(list2)  # [10, 50, 90]

# 当起始索引大于结束索引时,步长必须为负数,否则结果是空列表。
list1 = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100]
list2 = list1[7:2:-1]
print(list2)  # [80, 70, 60, 50, 40]

# 一个特殊情况:当同时省略起始索引和结束索引时,如果步长为负数,那Python会自动对调:起始位置和结束位置
list1 = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100]
list2 = list1[::-1]
print(list2)  # [100, 90, 80, 70, 60, 50, 40, 30, 20, 10]

# 对元组进行切片
tuple1 = (10, 20, 30, 40, 50, 60, 70, 80, 90, 100)
tuple2 = tuple1[0:5:1]
print(tuple2)  # (10, 20, 30, 40, 50)

# 对字符串进行切片
msg1 = 'welcome to atguigu'
msg2 = msg1[2:9:2]
print(msg2)  # (10, 20, 30, 40, 50)

6. 序列的其他操作

1️⃣序列相加: 把两个序列拼接在一起。

📢注意:只有同类型的序列才能相加(字符串+字符串、列表+列表、元组+元组)

# 列表相加
list1 = [10, 20, 30, 40]
list2 = [50, 60, 70, 80]
list3 = list1 + list2
print(list3)  # [10, 20, 30, 40, 50, 60, 70, 80]

# 元组相加
tuple1 = (10, 20, 30, 40)
tuple2 = (50, 60, 70, 80)
tuple3 = tuple1 + tuple2
print(tuple3)  # (10, 20, 30, 40, 50, 60, 70, 80)

# 字符换相加
str1 = 'hello'
str2 = 'atguigu'
str3 = str1 + str2
print(str3) # helloatguigu

# 错误示例
list1 = [10, 20, 30, 40]
str1 = 'hello'
print(list1 + str1) # 报错

2️⃣序列相乘(重复):把序列重复指定的次数。

# 序列相乘(重复)
list1 = [10, 20, 30, 40]
list2 = list1 * 3
print(list2)  # [10, 20, 30, 40, 10, 20, 30, 40, 10, 20, 30, 40]

tuple1 = (10, 20, 30, 40)
tuple2 = tuple1 * 3
print(tuple2)  # (10, 20, 30, 40, 10, 20, 30, 40, 10, 20, 30, 40)

str1 = 'hello'
str2 = str1 * 6
print(str2)  # hellohellohellohellohellohello

7. 集合

7.1. 概述

集合是一种:无序、元素唯一的容器类型。

📋备注:无序是指从集合中取出元素的顺序,与定义集合时存入的顺序不一定一致。

集合分为两种,分别是:

  • 可变集合(set):内部的元素无序(不保证顺序)、不能通过下标访问元素、会自动去除重复元素。
  • 不可变集合(forzenset):特点和可变集合一样,唯一的区别就是:其中的元素不可修改。

7.2. 定义集合

1️⃣可变集合的定义方式:使用花括号{}包裹,不同的数据项之间,用,做分隔。

# 定义有内容的【可变集合】
s1 = {10, 20, 20, 30, 40, 40, 50, 60, 60, 70, 80, 90, 100}
s2 = {'你好', 'hello', '你好', 'atguigu', '北京'}
s3 = {10, '你好', True, 1, 12.4}
print(type(s1), s1)  # <class 'set'> {100, 70, 40, 10, 80, 50, 20, 90, 60, 30}
print(type(s2), s2)  # <class 'set'> {'atguigu', 'hello', '你好', '北京'}
print(type(s3), s3)  # <class 'set'> {True, 10, '你好', 12.4}

# 定义空集合(可变集合)
s1 = set()
print(type(s1), s1)  # <class 'set'> set()

📢注意:不能直接写{}来定义空集合,因为直接写{}定义的是:空字典。

# 不能直接写{}来定义空集合,因为直接写{}定义的是:空字典
s2 = {}
print(type(s2), s2)  # <class 'dict'> {}

2️⃣不可变集合的定义方式:借助内置的forzenset函数。

# 定义有内容的【不可变集合】
s1 = frozenset({10, 20, 20, 30, 40, 40, 50, 60, 60, 70, 80, 90, 100})
s2 = frozenset({'你好', 'hello', '你好', 'atguigu', '北京'})
s3 = frozenset({10, '你好', True, 1, 12.4})
print(type(s1), s1)
print(type(s2), s2)
print(type(s3), s3)

# frozenset 接收的参数,可以是任意可迭代对象,但最终返回的一定是【不可变集合】
s1 = frozenset([10, 20, 30, 40, 50])
s2 = frozenset((10, 20, 30, 40, 50))
s3 = frozenset('hello')
print(type(s1), s1)
print(type(s2), s2)
print(type(s3), s3)

# 定义空集合(不可变集合)
s3 = frozenset()
print(type(s3), s3)

3️⃣集合中不能嵌套【可变集合】,但可以嵌套【不可变集合】

为什么会这样?—— 只有“不可变”的东西,才能安全的放进集合里。

# 集合中不能嵌套【可变集合】,但可以嵌套【不可变集合】
# 通俗理解:只有“不可变”的东西,才能安全的放进集合里
s1 = {10, 20, 30, 40, 50}
s2 = frozenset({100, 200, 300, 400, 500})
l1 = [666, 777, 888]
t1 = ('hello', 'atguigu', '北京')

s3 = {11, 22, 33, s1}  # 报错
s3 = {11, 22, 33, s2}  # 没问题
s3 = {11, 22, 33, l1}  # 报错
s3 = {11, 22, 33, t1}  # 没问题
print(s3)

7.3. 增删改查

1️⃣新增

方式1:使用集合.add(元素),向集合中添加元素,无返回值。

# add方法:向集合中添加元素
s1 = {10, 20, 30, 40, 50}
s1.add(60)
print(s1)

方式2:使用集合.update(元素),向集合中批量添加元素(接收可迭代对象),无返回值。

# update方法:向集合中添加元素(必须传递可迭代对象,例如:列表、元组、集合等)
s1 = {10, 20, 30, 40, 50}
s1.update([60, 70])
s1.update((80, 90))
s1.update({100, 200})
s1.update(range(300, 308))
print(s1)

2️⃣删除

方式1:使用集合.remove(元素),从集合中移除指定元素(若元素不存在,会报错),无返回值。

# remove方法:从集合中移除元素(移除不存在的元素,会报错)
s1 = {10, 20, 30, 40, 50}
s1.remove(20)
print(s1)

方式2:使用集合.discard(元素),从集合中移除指定元素(若元素不存在,不会报错),无返回值。

# discard方法:从集合中移除元素(移除不存在的元素,不会报错)
s1 = {10, 20, 30, 40, 50}
s1.discard(80)
print(s1)

方式3:使用集合.pop(),从集合中移除一个任意元素,返回值:移除的那个元素。

# pop方法:从集合中移除一个任意元素,返回值是移除的那个元素
s1 = {10, 20, 30, 40, 50}
s2 = {'你好', '北京', '', 'hello'}
result = s1.pop()
print(s1)
print(result)

方式4:使用集合.clear(),清空集合,无返回值。

# clear方法:清空集合
s1 = {10, 20, 30, 40, 50}
s1.clear()
print(s1)

3️⃣修改

📢注意:集合没有下标,也不支持replace方法,所以集合没有专门用于“改”的方法,但可以使用:remove+add的组合,来达到“修改”的效果。

# 改
# 使用 add + remove 的组合,来实现修改的效果
s1 = {10, 20, 30, 40, 50}
s1.remove(20)
s1.add(66)
print(s1)

4️⃣查询

📢注意:由于集合没有下标,也不支持切片操作,所以集合不具备按位置访问的能力。虽然不能通过下标读取元素,但可以使用【成员运算符】来判断:某个元素是否在集合中,成员运算符我们会放在后面讲,不过大家可以提前感受一下:

# 查:集合不能通过下标去读取元素,但能通过 【成员运算符】去查看集合中是否包含指定元素
# 由于成员运算符适用于所有数据容器,所以我们会等所有数据容器都讲完以后,再说成员运算符
s1 = {10, 20, 30, 40, 50}
# s1[0] # 此行报错,因为集合不能通过下标访问元素

# 先提前感受一下成员运算符
result = 20 not in s1
print(result)

7.4. 常用方法

集合常用的方法有如下几个:

1️⃣使用集合A.difference(集合B),找出集合A中,不同于集合B的元素。

# 集合A.difference(集合B):
# 作用:找出集合A中,不同于集合B的元素(集合A 与 集合B 都不变,返回的是一个新的集合)
s1 = {10, 20, 30, 40, 50}
s2 = {30, 40, 50, 60, 70}
result = s1.difference(s2)
print(s1)
print(s2)
print(result)

2️⃣使用集合A.difference_update(集合B),从集合A中,删除集合B中存在的元素。

# 集合A.difference_update(集合B):
# 作用:从集合A中,删除集合B中存在的元素(集合A会被修改,集合B不会)
s1 = {10, 20, 30, 40, 50}
s2 = {30, 40, 50, 60, 70}
s1.difference_update(s2)
print(s1)
print(s2)

3️⃣使用集合A.union(集合B),合并两个集合,集合A 和 集合B 都不变,返回的是一个新的集合。

# 集合A.union(集合B):
# 作用:合并两个集合,集合A 和 集合B 都不变,返回的是一个新的集合
s1 = {10, 20, 30, 40, 50}
s2 = {30, 40, 50, 60, 70}
result = s2.union(s1)
print(s1)
print(s2)
print(result)

4️⃣使用集合A.issubset(集合B),判断集合A是否为集合B的子集,返回值为布尔值。

# 集合A.issubset(集合B):
# 作用:判断集合A是否为集合B的子集
# 如果 集合A的所有元素都在集合B中,那就返回True,否则返回False
s1 = {10, 20, 30, 40, 50}
s2 = {30, 40, 50, 60, 70}
s3 = {30, 40, 50}
result = s3.issubset(s1)
print(result)

5️⃣使用集合A.issuperset(集合B),判断集合A是否是集合B的超集,返回值为布尔值。

# 集合A.issuperset(集合B):
# 作用:判断集合A是否是集合B的超集
# 如果集合A中,包含了集合B中的所有元素,那就返回True,否则返回False
s1 = {10, 20, 30, 40, 50}
s2 = {30, 40, 50, 60, 70}
s3 = {30, 40, 50}
result = s1.issuperset(s3)
print(result)

6️⃣使用集合A.isdisjoint(集合B),判断集合A和集合B是否没有交集,返回值为布尔值。

# 集合A.isdisjoint(集合B):
# 作用:
# 如果没有交集,返回True;只要有一个公共元素,就返回False
s1 = {10, 20, 30, 40, 50}
s2 = {30, 40, 50, 60, 70}
s3 = {80, 90}
result = s1.isdisjoint(s2)
print(result)

7.5. 集合的数学运算

集合的数学运算如下:

s1 = {10, 20, 30, 40, 50, 60}
s2 = {40, 50, 60, 70, 80, 90}

# 并集
result = s1 | s2
print(result)

# 交集
result = s1 & s2
print(result)

# 差集
result = s1 - s2
print(result)

# 对称差集
result = s1 ^ s2
print(result)

7.6. 集合的循环遍历

由于集合不支持下标,所以集合不能使用 while 循环遍历。

s1 = {10, 20, 30, 40, 50, 60}

# 集合不能使用while循环遍历(以下是错误示例)
# index = 0
# while index < len(s1):
#     print(s1[index])
#     index += 1

# 集合可以使用for循环遍历
for item in s1:
    print(item)

7.7. 集合特点总结

  • 无序:集合中的元素没有固定顺序,无法通过下标访问。
  • 不重复:集合会自动去重,同一个元素只会保留一份。
  • 分为两种:可变集合合(set)和不可变集合(forzenset)。
  • 集合中的元素必须是不可变类型(如:数字、字符串、元组)。
  • 集合支持:并集、交集、差集、对称差集等数学操作。

📍一句话总结:集合是可以去重的数据容器,当只关心元素是否存在,而不在乎顺序的时,首选集合。

赞(0)
未经允许不得转载:AI项目博客 » Python 学习笔记 13|序列的切片操作

评论 抢沙发

AI项目博客

专注 AI 工程化落地 —— 覆盖智能体、大模型、Java AI 与 Python 的学习笔记,以及 AI 平台的项目实战记录。

关于本站文章归档

登录

找回密码

注册