展开菜单
首页 精品内容 本月促销 装机必备 Windows PDF教程 macOS软件 IOS软件 Android AI 专题
全部分类

当前位置:

首页 > 编程开发 > Python基础指南之列表切片操作的高级应用场景

Python基础指南之列表切片操作的高级应用场景

Python列表切片支持永不越界的访问(安全返回空列表),可创建浅拷贝,实现原地修改长度、插入删除元素,支持带步长赋值与反转序列,还能用于降采样、批量交换等操作,是Python列表的核心特性,极大提升编程效率。

本文目录

    聊到Python列表,就绕不开一个堪称“核武器”的特性——切片(Slice)。如果你用过Ja va或C++,一定还记得用循环提取子数组时那种繁琐的体验。而在Python里,一行 lst[2:8:2] 就能完成那些语言需要五六行代码才能搞定的事。

    Python基础指南之列表切片操作的高级应用场景

    但切片远不止“取一段数据”这么简单。它还能原地修改列表长度、反转序列、优雅地处理边界情况、实现高效的批量赋值。这篇文章就来系统地梳理一下切片的所有高级应用场景,看看它到底能玩出多少花样。

    一、切片的基础回顾与深入理解

    1.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]
    

    1.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]
    

    1.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
    

    二、切片的强大特性

    2.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
    
    # 切片访问:越界就截断或返回空,永不出错
    # 这个特性让很多边界处理的代码变简单了
    

    2.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]](不受影响)
    

    2.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的切片是视图。在数据科学领域切换时,这一点特别值得注意。

    三、用切片原地修改列表

    3.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]
    

    3.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]
    

    3.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]
    

    3.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])赋值不受此限,可以改变列表长度
    

    四、切片的实用技巧大全

    4.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
    

    4.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()最慢
    

    4.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]
    

    4.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]
    

    4.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]
    

    五、切片的高级应用场景

    5.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"]}')
    

    5.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行日志:一切正常
    

    5.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))
    

    5.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]
    

    六、切片对象——可复用的切片

    6.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])
    

    6.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
    

    6.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])
    

    七、切片的性能与陷阱

    7.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)
    

    7.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]
    

    八、综合实战:用切片优雅解决实际问题

    8.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
    

    8.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))
    

    8.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中最强大、最常用的序列操作工具,值得好好消化:

    1. 完整语法:lst[start:stop:step],三个参数都可以省略,默认值根据step的正负确定
    2. 永不越界:切片访问永远不会报IndexError,越界自动截断——这是它和索引访问的关键区别
    3. 原地修改:lst[a:b] = values可以增删改列表元素,lst[a:a] = values在任意位置插入,lst[a:b] = []删除一段
    4. 浅拷贝:lst[:]创建新列表,但内层对象共享(嵌套列表要注意)
    5. 切片对象:slice(start, stop, step)可复用切片规则,.indices(len)规范化参数
    6. 带步长的切片赋值:右边长度必须和切片结果长度一致

    切片操作是Python编程中的“基本功”,但用好了就是“杀手锏”。熟练运用切片,能让代码减少一半的循环和条件判断。下一篇将进入列表的增删改查方法详解——从增加元素的四大方式开始。

    本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
    作者最新文章
    编程开发 Python
    相关文章 更多
    精品专题 更多
    装机必备

    正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

    Windows

    正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

    PDF教程

    正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

    macOS软件

    正软商城macOS软件专区,精选适用于Mac电脑的办公、设计、影音、效率、开发和系统工具,提供软件功能介绍、macOS兼容版本、正版授权及购买下载服务。

    IOS软件

    正软商城iOS软件专区,精选适用于iPhone和iPad的办公、学习、影音、设计、效率及AI应用,提供功能介绍、适用设备、系统要求和正版获取方式等信息。

    AI

    正软商城AI软件专区,汇集AI写作、AI绘画、AI视频、AI办公、AI编程、AI翻译、智能客服和数据分析等人工智能工具,提供功能介绍、适用平台、收费方式及正版购买信息。

    Mac软件 更多
    讯飞智作 网页版
    讯飞智作 网页版

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    Aperty macOS版
    Aperty macOS版

    Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

    立刻MV 网页版
    立刻MV 网页版

    立刻MV 面向音乐人、内容创作者和品牌团队,帮助用户低成本完成歌曲 MV、歌词视频、AI 分镜、图生视频与最终合成。

    蛙蛙写作 网页版
    蛙蛙写作 网页版

    蛙蛙写作 AI 创作工具,覆盖小说、剧本、文案,一键生成文稿,打通文字转视频全流程,高效解决创作难题。

    超级简历WonderCV 网页版
    超级简历WonderCV 网页版

    超级简历WonderCV是面向应届生和AI小白的智能求职平台,覆盖简历、面试与职业规划。

    音述AI 网页版
    音述AI 网页版

    音述AI,是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区。

    AionClaw macOS版
    AionClaw macOS版

    AionClaw 是可在桌面端运行的任务型 AI 助手,通过数字专家与技能市场组合办公、创作、数据和开发能力。

    Loomy macOS版
    Loomy macOS版

    Loomy 是科大讯飞推出的桌面 AI 助手,可通过对话、任务与工作目录协助处理办公、内容创作和资料整理。

    AirBuddy 3 macOS版
    AirBuddy 3 macOS版

    AirBuddy 3 是面向 macOS 的蓝牙外设增强工具,可集中查看 AirPods、Beats 与苹果设备电量,提供快速连接、播放控制、电量提醒、桌面小组件和多台 Mac 外设接力等功能。

    AirServer macOS版
    AirServer macOS版

    AirServer macOS版可把 Mac 转换为无线投屏接收端,通过 AirPlay 或 Google Cast 接收手机、平板和电脑画面,并支持多设备同时连接、高清镜像及会话录制,适合家庭娱乐、课堂教学、会议演示和应用展示。

    AnyDesk macOS版
    AnyDesk macOS版

    AnyDesk macOS版是一款适用于远程办公、设备维护和客户支持的远程桌面工具,可连接并操作异地计算机,支持文件传输、无人值守访问、会话权限控制及跨平台协作。

    WINDOWS 更多
    讯飞智作 网页版
    讯飞智作 网页版

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    PixTV 网页版
    PixTV 网页版

    PixTV 是一款在浏览器中使用的 AI 视觉内容创作平台,提供图片、视频、音频、文字生成、AI 分镜、局部重绘、提示词反推和无限画布等工具,适合短剧、漫剧、广告及社交媒体内容制作。

    讯飞绘文 网页版
    讯飞绘文 网页版

    讯飞绘文网页版是科大讯飞推出的AI图文创作与内容运营工具,覆盖热点选题、文章生成、稿件校对、智能配图、排版发布和数据复盘等环节,适合自媒体创作者及内容团队在线使用。

    Maya(Autodesk Maya) Windows版
    Maya(Autodesk Maya) Windows版

    Autodesk Maya 是面向影视、电视、动画和游戏行业的专业三维制作软件,集多边形与 NURBS 建模、角色绑定、关键帧和动作捕捉动画、Bifrost 特效模拟、材质开发及 Arnold 渲染于一体,

    Aperty Windows版
    Aperty Windows版

    Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

    立刻MV 网页版
    立刻MV 网页版

    立刻MV 面向音乐人、内容创作者和品牌团队,帮助用户低成本完成歌曲 MV、歌词视频、AI 分镜、图生视频与最终合成。

    蛙蛙写作 网页版
    蛙蛙写作 网页版

    蛙蛙写作 AI 创作工具,覆盖小说、剧本、文案,一键生成文稿,打通文字转视频全流程,高效解决创作难题。

    超级简历WonderCV 网页版
    超级简历WonderCV 网页版

    超级简历WonderCV是面向应届生和AI小白的智能求职平台,覆盖简历、面试与职业规划。

    音述AI 网页版
    音述AI 网页版

    音述AI,是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区。

    AionClaw Windows版
    AionClaw Windows版

    AionClaw 是可在桌面端运行的任务型 AI 助手,通过数字专家与技能市场组合办公、创作、数据和开发能力。

    Loomy Windows版
    Loomy Windows版

    Loomy 是科大讯飞推出的桌面 AI 助手,可通过对话、任务与工作目录协助处理办公、内容创作和资料整理。