Python基础指南之列表切片操作的高级应用场景
作者:星河耀银海
切片操作可能是Python区别于其他编程语言最鲜明的特性之一,在Python中,一行 lst[2:8:2] 就能完成那些语言需要五六行代码才能做到的事,本文会把切片的所有高级应用场景一一拆解,希望对大家有所帮助
一、开篇:切片是Python列表的核武器
今天我们要重点突破Python中最强大、最独特的特性之一——切片(Slice)。
切片操作可能是Python区别于其他编程语言最鲜明的特性之一。如果你用过Java或C++,你一定记得用循环提取子数组的繁琐。而在Python中,一行 lst[2:8:2] 就能完成那些语言需要五六行代码才能做到的事。
但切片远不止"取一段数据"这么简单。它可以原地修改列表的长度、反转序列、优雅地处理边界情况、实现高效的批量赋值。今天这篇文章,我会把切片的所有高级应用场景一一拆解给你看。
二、切片的基础回顾与深入理解
2.1 切片的完整语法
lst = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] # 完整语法:lst[start:stop:step] # start:起始索引(包含),默认:step>0时为0,step<0时为-1 # stop:结束索引(不包含),默认:step>0时为len(lst),step<0时为-len(lst)-1 # step:步长,默认1(不能为0) # 从索引2到索引7(步长为2) print(lst[2:7:2]) # [2, 4, 6] # 从索引8到索引2(反向步长为2) print(lst[8:2:-2]) # [8, 6, 4]
2.2 切片默认值的完整规则
lst = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] # 当step > 0(正向)时: # - start默认值 = 0 # - stop默认值 = len(lst) # 以下等价: print(lst[0:10:1]) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] print(lst[::1]) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] print(lst[:]) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] print(lst[0::1]) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] print(lst[:10:1]) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] # 当step < 0(反向)时: # - start默认值 = len(lst) - 1(即-1,最后一个元素) # - stop默认值 = -len(lst) - 1(即取到最前面) # 以下等价: print(lst[::-1]) # [9, 8, 7, 6, 5, 4, 3, 2, 1, 0] print(lst[-1:-11:-1]) # [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
2.3 切片参数的计算规则
# 理解切片中的索引计算 lst = [10, 20, 30, 40, 50, 60, 70, 80] # 索引:0 1 2 3 4 5 6 7 # 规则:lst[start:stop:step] 包含索引 start, start+step, start+2*step, ... # 直到达到或越过 stop # 例:lst[1:6:2] # 索引序列:1, 1+2=3, 3+2=5 → 索引1, 3, 5 # 下一个 5+2=7 ≥ stop=6,停止 print(lst[1:6:2]) # [20, 40, 60] # 例:lst[6:1:-2] # 索引序列:6, 6-2=4, 4-2=2 → 索引6, 4, 2 # 下一个 2-2=0 ≤ stop=1,停止 print(lst[6:1:-2]) # [70, 50, 30] # 核心记忆:step的正负决定方向,包含start不包含stop
三、切片的强大特性
3.1 切片不越界——这是最实用的特性
lst = [1, 2, 3, 4, 5] # 无论start和stop有多大或多小,切片都不会报错 print(lst[0:100]) # [1, 2, 3, 4, 5](自动截断) print(lst[-100:3]) # [1, 2, 3] print(lst[10:20]) # [](start超出范围,返回空列表) print(lst[-10:-20]) # [](空范围,返回空列表) print(lst[100:0]) # [](start > stop,返回空列表) # 这就是为什么切片比索引更适合处理边界模糊的情况 # 索引访问:越界就报错 # lst[100] # IndexError # 切片访问:越界就截断或返回空,永不出错 # 这个特性让很多边界处理的代码变简单了
3.2 切片创建的是浅拷贝
original = [1, 2, 3] sliced = original[:] # 创建副本 # 修改原列表不影响切片 original[0] = 999 print(original) # [999, 2, 3] print(sliced) # [1, 2, 3] # 但对于嵌套列表,内层对象是共享的 nested = [[1, 2], [3, 4]] copy_nested = nested[:] nested[0][0] = 999 print(nested) # [[999, 2], [3, 4]] print(copy_nested) # [[999, 2], [3, 4]](内层共享!) # 如果需要完全独立的副本,用copy.deepcopy import copy deep = copy.deepcopy(nested) nested[0][0] = 111 print(nested) # [[111, 2], [3, 4]] print(deep) # [[999, 2], [3, 4]](不受影响)
3.3 切片的独立性——对切片赋值会影响原列表
# 用切片获取一个视图...等等,Python的切片返回的是新列表,不是视图! # 这一点和NumPy不一样 lst = [1, 2, 3, 4, 5] view = lst[1:4] # 这是一个新列表! view[0] = 999 print(lst) # [1, 2, 3, 4, 5](原列表不变) print(view) # [999, 3, 4] # 这一点和NumPy数组的行为不同 import numpy as np arr = np.array([1, 2, 3, 4, 5]) arr_view = arr[1:4] # NumPy的切片是视图(共享底层数据) arr_view[0] = 999 print(arr) # [ 1 999 3 4 5](原数组也被改了!) print(arr_view) # [999 3 4] # Python列表使用这种方式原地修改切片区域: lst[1:4] = [999, 999, 999] print(lst) # [1, 999, 999, 999, 5](原列表被修改了)
这是Python列表和NumPy数组的一个重要区别。Python列表的切片总是创建新列表,而NumPy的切片是视图。在数据科学领域切换时特别注意。
四、用切片原地修改列表
4.1 切片赋值:替换任意范围的元素
nums = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] # 替换中间一段 nums[3:7] = [30, 40, 50, 60] print(nums) # [0, 1, 2, 30, 40, 50, 60, 7, 8, 9] # 替换为更长的序列——列表变长! nums[3:7] = [30, 40, 50, 60, 70, 80] print(nums) # [0, 1, 2, 30, 40, 50, 60, 70, 80, 7, 8, 9] # 替换为更短的序列——列表变短! nums[3:9] = [300] print(nums) # [0, 1, 2, 300, 7, 8, 9] # 替换为空——删除一段元素 nums[2:5] = [] print(nums) # [0, 1, 7, 8, 9]
4.2 在任意位置插入元素
nums = [1, 5, 9] # 在索引1处插入多个元素 nums[1:1] = [2, 3, 4] print(nums) # [1, 2, 3, 4, 5, 9] # 在开头插入 nums[:0] = [-1, 0] print(nums) # [-1, 0, 1, 2, 3, 4, 5, 9] # 在末尾插入 nums[len(nums):] = [10, 11] print(nums) # [-1, 0, 1, 2, 3, 4, 5, 9, 10, 11] # 在中间插入 mid = len(nums) // 2 nums[mid:mid] = ['中'] print(nums) # [-1, 0, 1, 2, 3, 4, '中', 5, 9, 10, 11]
4.3 删除任意范围的元素
nums = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] # 删除前3个 nums[:3] = [] print(nums) # [3, 4, 5, 6, 7, 8, 9] # 删除后3个 nums[-3:] = [] print(nums) # [3, 4, 5, 6] # 删除偶数位置(每隔一个) nums[::2] = [] print(nums) # [4, 6] # 注意:`del lst[::2]` 和 `lst[::2] = []` 效果相同 nums = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] del nums[::2] print(nums) # [1, 3, 5, 7, 9]
4.4 带步长的切片赋值——有严格限制
nums = [0, 1, 2, 3, 4, 5] # 带步长的切片赋值:右边的长度必须和切片结果长度一致! nums[::2] = [10, 20, 30] # 3个元素对3个位置 print(nums) # [10, 1, 20, 3, 30, 5] # ❌ 长度不匹配会报错 # nums[::2] = [10, 20] # ValueError: attempt to assign sequence of size 2 to extended slice of size 3 # nums[::2] = [10, 20, 30, 40] # ValueError # 这个限制只在步长≠1时存在 # 步长为1的切片(lst[a:b])赋值不受此限,可以改变列表长度
五、切片的实用技巧大全
5.1 反转序列
# 方式一:[::-1](最常用)
lst = [1, 2, 3, 4, 5]
reversed_lst = lst[::-1]
print(reversed_lst) # [5, 4, 3, 2, 1]
# 方式二:reversed()(返回迭代器,不创建新列表)
for item in reversed(lst):
print(item, end=' ') # 5 4 3 2 1
print()
# 方式三:list.reverse()(原地反转,不创建新列表)
lst.reverse()
print(lst) # [5, 4, 3, 2, 1]
# 性能对比
# lst[::-1]:创建新列表,O(n)内存
# lst.reverse():原地反转,O(1)额外内存
# reversed(lst):懒迭代,O(1)额外内存
# 反向字符串
text = 'hello world'
print(text[::-1]) # dlrow olleh
5.2 浅拷贝的多种写法
original = [1, 2, 3, 4, 5]
# 三种等价的浅拷贝方式
copy1 = original[:]
copy2 = original.copy()
copy3 = list(original)
# 它们创建的都是浅拷贝
print(copy1 == copy2 == copy3) # True
print(copy1 is original) # False
# 哪种最快?实际测试:
import time
n = 1000000
lst = list(range(100))
start = time.perf_counter()
for _ in range(n):
c = lst[:]
print(f'[:] {time.perf_counter() - start:.3f}秒')
start = time.perf_counter()
for _ in range(n):
c = lst.copy()
print(f'.copy() {time.perf_counter() - start:.3f}秒')
start = time.perf_counter()
for _ in range(n):
c = list(lst)
print(f'list() {time.perf_counter() - start:.3f}秒')
# .copy()通常最快(因为是直接的C方法调用),[:]次之,list()最慢
5.3 每隔N个取一个元素
lst = list(range(30))
# 每隔2个取一个(所有偶数索引)
print(lst[::2])
# [0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28]
# 每隔3个取一个
print(lst[::3])
# [0, 3, 6, 9, 12, 15, 18, 21, 24, 27]
# 从第2个开始,每隔4个取一个
print(lst[1::4])
# [1, 5, 9, 13, 17, 21, 25, 29]
# 实际应用:对列表进行降采样
def downsample(lst, factor):
"""将列表降采样为原来的1/factor"""
return lst[::factor]
original = list(range(100))
reduced = downsample(original, 10)
print(reduced) # [0, 10, 20, 30, 40, 50, 60, 70, 80, 90]
5.4 批量交换元素位置
# 将列表的前半部分和后半部分互换
def swap_halves(lst):
mid = len(lst) // 2
# 注意:直接赋值会改变原列表
lst[:] = lst[mid:] + lst[:mid]
nums = [1, 2, 3, 4, 5, 6]
swap_halves(nums)
print(nums) # [4, 5, 6, 1, 2, 3]
# 循环左移k位
def rotate_left(lst, k):
k %= len(lst)
lst[:] = lst[k:] + lst[:k]
nums = [1, 2, 3, 4, 5, 6, 7]
rotate_left(nums, 2)
print(nums) # [3, 4, 5, 6, 7, 1, 2]
# 循环右移k位
def rotate_right(lst, k):
k %= len(lst)
lst[:] = lst[-k:] + lst[:-k]
nums = [1, 2, 3, 4, 5, 6, 7]
rotate_right(nums, 2)
print(nums) # [6, 7, 1, 2, 3, 4, 5]
5.5 列表"压缩"——去除特定位置的元素
# 去除所有偶数索引位置的元素 lst = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'] del lst[::2] print(lst) # ['b', 'd', 'f', 'h'] # 去除所有奇数索引位置的元素 lst = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'] del lst[1::2] print(lst) # ['a', 'c', 'e', 'g'] # 保留前3个和后3个,删除中间的 lst = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] lst[3:-3] = [] print(lst) # [0, 1, 2, 7, 8, 9]
六、切片的高级应用场景
6.1 数据分页
def paginate(items, page, page_size):
"""用切片实现数据分页"""
start = (page - 1) * page_size
end = start + page_size
return items[start:end]
# 模拟数据库查询结果
all_data = list(range(1, 101)) # 100条数据
page_size = 10
# 第1页
print(f'第1页: {paginate(all_data, 1, page_size)}')
# 第3页
print(f'第3页: {paginate(all_data, 3, page_size)}')
# 最后一页(可能不满一页)
print(f'第10页: {paginate(all_data, 10, page_size)}')
# 超出范围返回空列表(不会报错)
print(f'第20页: {paginate(all_data, 20, page_size)}') # []
def paginate_with_info(items, page, page_size):
"""带分页信息的分页"""
total = len(items)
total_pages = (total + page_size - 1) // page_size
page = max(1, min(page, total_pages))
start = (page - 1) * page_size
end = min(start + page_size, total)
return {
'items': items[start:end],
'page': page,
'page_size': page_size,
'total': total,
'total_pages': total_pages,
'has_prev': page > 1,
'has_next': page < total_pages,
}
info = paginate_with_info(all_data, 1, 10)
print(f'第{info["page"]}页/共{info["total_pages"]}页')
print(f'数据: {info["items"]}')
print(f'有上一页: {info["has_prev"]}, 有下一页: {info["has_next"]}')
6.2 文本处理和截断
# 截断长文本,加省略号
def truncate(text, max_length, ellipsis='...'):
"""用切片实现文本截断"""
if len(text) <= max_length:
return text
return text[:max_length - len(ellipsis)] + ellipsis
long_text = '这是一段很长的文本内容,我们需要将其截断显示'
print(truncate(long_text, 15)) # 这是一段很长的文本内容,我...
# 提取摘要(取前N个字符)
def summary(text, n=100):
return text[:n]
# 取文本的最后N行
def last_n_lines(text, n):
lines = text.splitlines()
return '\n'.join(lines[-n:])
log = '\n'.join(f'第{i}行日志:一切正常' for i in range(1, 101))
print(last_n_lines(log, 3))
# 第98行日志:一切正常
# 第99行日志:一切正常
# 第100行日志:一切正常
6.3 批量赋值模式
# 初始化部分元素
nums = [0] * 10
# 将前5个设为1
nums[:5] = [1] * 5
print(nums) # [1, 1, 1, 1, 1, 0, 0, 0, 0, 0]
# 交替模式
nums = [0] * 10
nums[::2] = [1] * 5 # 偶数位为1
print(nums) # [1, 0, 1, 0, 1, 0, 1, 0, 1, 0]
# 更复杂的模式——棋盘格
size = 8
row_template = [0] * size
row_template[::2] = [1] * (size // 2)
# row_template = [1, 0, 1, 0, 1, 0, 1, 0]
board = []
for i in range(size):
if i % 2 == 0:
board.append(row_template[:])
else:
board.append(row_template[::-1])
for row in board:
print(' '.join('█' if c else ' ' for c in row))
6.4 螺旋遍历矩阵
def spiral_order(matrix):
"""用切片实现矩阵的螺旋遍历"""
result = []
while matrix:
# 取第一行
result.extend(matrix[0])
# 去掉第一行,然后逆时针旋转矩阵
matrix = matrix[1:]
if matrix:
# 逆时针旋转 = 转置 + 行反转
matrix = [list(row) for row in zip(*matrix)][::-1]
return result
matrix = [
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12],
]
print(spiral_order(matrix))
# [1, 2, 3, 4, 8, 12, 11, 10, 9, 5, 6, 7]
七、切片对象——可复用的切片
7.1 使用slice()创建切片对象
# slice(start, stop, step)创建切片对象 s = slice(2, 8, 2) print(s) # slice(2, 8, 2) lst = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] print(lst[s]) # [2, 4, 6](和lst[2:8:2]完全一样) # 切片对象可以复用 data1 = list(range(100)) data2 = list(range(100, 200)) data3 = list(range(200, 300)) # 定义好切片规则,到处使用 first_half = slice(None, 50) # 等价于 [:50] last_quarter = slice(-25, None) # 等价于 [-25:] every_10th = slice(None, None, 10) # 等价于 [::10] print(data1[first_half]) print(data2[last_quarter]) print(data3[every_10th])
7.2 切片对象的属性
s = slice(2, 10, 3)
print(s.start) # 2
print(s.stop) # 10
print(s.step) # 3
# indices()方法:根据序列长度规范化切片参数
lst = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
print(s.indices(len(lst))) # (2, 10, 3)
# 这意味着实际提取的是索引2, 5, 8
# 当切片参数超出范围时,indices()会自动修正
s2 = slice(5, 100, 2)
print(s2.indices(10)) # (5, 10, 2)(stop从100修正为10)
s3 = slice(-100, 3, 1)
print(s3.indices(10)) # (0, 3, 1)(start从-100修正为0)
# 用indices()实现自己的安全切片操作
def my_slice(sequence, slice_obj):
"""使用slice对象的通用安全切片"""
start, stop, step = slice_obj.indices(len(sequence))
result = []
i = start
if step > 0:
while i < stop:
result.append(sequence[i])
i += step
else:
while i > stop:
result.append(sequence[i])
i += step
return type(sequence)(result) if hasattr(type(sequence), '__call__') else result
7.3 切片在自定义类中的应用
class DataSeries:
"""自定义的数据库列——演示如何支持切片操作"""
def __init__(self, data):
self._data = list(data)
def __getitem__(self, key):
"""支持索引和切片"""
if isinstance(key, slice):
# 可以用indices()规范化切片参数
start, stop, step = key.indices(len(self._data))
result = [self._data[i] for i in range(start, stop, step)]
return DataSeries(result)
elif isinstance(key, int):
return self._data[key]
else:
raise TypeError(f'不支持的索引类型:{type(key)}')
def __setitem__(self, key, value):
"""支持索引赋值和切片赋值"""
if isinstance(key, slice):
self._data[key] = value
elif isinstance(key, int):
self._data[key] = value
else:
raise TypeError(f'不支持的索引类型:{type(key)}')
def __delitem__(self, key):
"""支持通过切片删除"""
if isinstance(key, slice):
del self._data[key]
elif isinstance(key, int):
del self._data[key]
def __len__(self):
return len(self._data)
def __repr__(self):
return f'DataSeries({self._data})'
ds = DataSeries([10, 20, 30, 40, 50, 60, 70, 80, 90, 100])
# 使用切片
print(ds[2:5]) # DataSeries([30, 40, 50])
print(ds[::2]) # DataSeries([10, 30, 50, 70, 90])
print(ds[::-1]) # DataSeries([100, 90, 80, 70, 60, 50, 40, 30, 20, 10])
# 切片赋值
ds[2:5] = [300, 400, 500]
print(ds) # DataSeries([10, 20, 300, 400, 500, 60, 70, 80, 90, 100])
# 切片删除
del ds[3:7]
print(ds) # DataSeries([10, 20, 300, 70, 80, 90, 100])
八、切片的性能与陷阱
8.1 切片的内存消耗
import sys
# 切片总是创建新列表——对大列表会导致内存翻倍
large_list = list(range(10000000)) # 1000万元素
# 取一小段也会创建新列表(虽然只包含几个元素)
small_slice = large_list[1000:1010]
print(f'原列表大小: {sys.getsizeof(large_list):,} 字节')
print(f'切片大小: {sys.getsizeof(small_slice):,} 字节')
# 如果只需要遍历,不需要切片
# 不推荐(创建新列表)
for item in large_list[1000:1010]:
print(item)
# 推荐(用islice避免创建新列表)
from itertools import islice
for item in islice(large_list, 1000, 1010):
print(item)
8.2 切片的常见陷阱
# 陷阱一:忘记切片是浅拷贝 original = [[0]] * 5 copy = original[:] copy[0][0] = 999 print(original) # [[999], [999], [999], [999], [999]](所有元素都变了!) print(copy) # [[999], [999], [999], [999], [999]] # 陷阱二:对切片赋值 vs 对切片变量赋值 lst = [1, 2, 3, 4, 5] s = lst[1:4] # s是一个新列表 s[0] = 100 # 修改s不影响lst print(lst) # [1, 2, 3, 4, 5](lst没变) lst[1:4] = [100, 100, 100] # 这是切片赋值,修改lst本身 print(lst) # [1, 100, 100, 100, 5] # 陷阱三:带步长的切片赋值长度必须匹配 lst = [0, 1, 2, 3, 4, 5] # lst[::2] = [10, 20] # ValueError(3个位置但只给了2个值) # 陷阱四:负数步长时start应大于stop lst = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] print(lst[2:8:2]) # [2, 4, 6](正确) print(lst[8:2:-2]) # [8, 6, 4](正确) print(lst[2:8:-2]) # [](空!start < stop,反向步长取不到值) # 陷阱五:给切片赋值的右边不一定是列表 lst = [1, 2, 3, 4, 5] lst[1:4] = 'XYZ' # 字符串被拆为字符序列 print(lst) # [1, 'X', 'Y', 'Z', 5] lst[1:4] = range(100, 103) # range也是可迭代对象 print(lst) # [1, 100, 101, 102, 5]
九、综合实战:用切片优雅解决实际问题
9.1 回文判断
def is_palindrome(s):
"""用切片判断回文"""
# 去掉非字母数字字符,统一小写
cleaned = ''.join(c.lower() for c in s if c.isalnum())
return cleaned == cleaned[::-1]
print(is_palindrome('A man, a plan, a canal: Panama')) # True
print(is_palindrome('race a car')) # False
print(is_palindrome('上海自来水来自海上')) # True
9.2 杨辉三角
def pascal_triangle(n):
"""生成杨辉三角——用切片轻松实现"""
result = [[1]]
for _ in range(1, n):
prev = result[-1]
# 核心:每行前后补0,相邻元素相加
current = [1] + [prev[i] + prev[i + 1] for i in range(len(prev) - 1)] + [1]
result.append(current)
return result
# 更Pythonic的写法(用切片)
def pascal_triangle_v2(n):
result = [[1]]
for _ in range(1, n):
prev = [0] + result[-1] + [0]
current = [prev[i] + prev[i + 1] for i in range(len(prev) - 1)]
result.append(current)
return result
for row in pascal_triangle_v2(8):
print(' '.join(f'{x:3d}' for x in row).center(40))
9.3 格式化输出对齐
def format_columns(data, col_widths):
"""用切片分列展示数据"""
result = []
for row in data:
formatted = [str(cell)[:w].ljust(w) for cell, w in zip(row, col_widths)]
result.append(' | '.join(formatted))
return '\n'.join(result)
headers = ['姓名', '年龄', '城市', '职业']
rows = [
['小明', 25, '北京', '软件工程师'],
['小红', 23, '上海', 'UI设计师'],
['Alexander Hamilton', 26, '广州', '数据科学家'],
]
# 计算列宽
col_widths = []
for i in range(len(headers)):
max_w = max(len(str(row[i])) for row in [headers] + rows)
col_widths.append(max_w + 2)
print(format_columns([headers] + rows, col_widths))
十、本篇小结
切片是Python中最强大、最常用的序列操作工具:
- 完整语法:
lst[start:stop:step],三个参数都可以省略,默认值根据step的正负确定 - 永不越界:切片访问永远不会报IndexError,越界自动截断——这是它和索引访问的关键区别
- 原地修改:
lst[a:b] = values可以增删改列表元素,lst[a:a] = values在任意位置插入,lst[a:b] = []删除一段 - 浅拷贝:
lst[:]创建新列表,但内层对象共享(嵌套列表要注意) - 切片对象:
slice(start, stop, step)可复用切片规则,.indices(len)规范化参数 - 带步长的切片赋值:右边长度必须和切片结果长度一致
切片操作是Python编程中的"基本功",但用好了就是"杀手锏"。熟练运用切片可以让你的代码减少一半的循环和条件判断。下一篇我们将进入列表的增删改查方法详解——从增加元素的四大方式开始。
到此这篇关于Python基础指南之列表切片操作的高级应用场景的文章就介绍到这了,更多相关Python列表切片内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
