尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

Python列表从入门到精通:创建、切片、增删改查与性能优化全解析

Python列表从入门到精通:创建、切片、增删改查与性能优化全解析 1. 项目概述为什么列表是Python入门的第一个“坎”如果你刚开始学Python学完变量、数据类型和基础语法感觉一切都很顺畅那么恭喜你马上要遇到第一个真正能让你感受到编程威力的东西了——列表。很多人把列表当作一个简单的“数据容器”来学这其实大大低估了它的价值。在我带过的很多新手项目中列表是第一个分水岭会用列表和真正理解列表的人写出的代码效率和可读性天差地别。简单说列表就是一个可以装下任何东西的“魔法口袋”。你可以把数字、字符串、甚至其他列表都塞进去并且能随时取出、替换、增加或删除。这节课我们不搞那些枯燥的教科书定义就从一个实际场景切入假设你要管理一个线上读书会成员的信息包括名字、加入月份和本月阅读时长小时。用单个变量存你得声明几十个变量管理起来是场灾难。用列表一行代码就能轻松搞定。这就是列表要解决的第一个核心问题如何高效地组织和管理一组有序的、可能随时变化的数据。这节课是“常用数据结构之列表”的第一部分我们会聚焦在最核心、最常用的操作上。目标是让你学完就能立刻用起来处理你手头的数据。我们会从创建和访问这个“口袋”开始到如何往里面“放东西”、“拿东西”、“换东西”最后深入到“切片”这个列表的灵魂操作。别被“数据结构”这个词吓到你就把它理解为“整理数据的工具箱”而列表是你打开工具箱后最顺手、最常用的那把螺丝刀。2. 列表的核心操作全解析从创建到访问2.1 创建列表的四种姿势与选择逻辑创建列表Python给了你极大的灵活性但不同的方式适用于不同的场景选对了能让代码意图更清晰。第一种也是最直接的方式使用方括号[]。# 创建一个空列表像一个准备装东西的空盒子 members [] # 创建一个包含初始元素的列表 book_club_members [‘Alice‘, ‘Bob‘, ‘Charlie‘] reading_hours [12, 8, 15]这是你未来90%的情况下会使用的方式。它直观、简洁一眼就能看出你在定义一个列表。空列表常用于初始化一个后续需要动态填充的数据容器比如在循环中收集结果。第二种使用list()构造函数。# 将其他可迭代对象转换为列表 name_tuple (‘Alice‘, ‘Bob‘) # 这是一个元组 member_list_from_tuple list(name_tuple) # 转换成列表[‘Alice‘, ‘Bob‘] # 将字符串的每个字符拆成列表 letters list(‘Python‘) # 结果[‘P‘, ‘y‘, ‘t‘, ‘h‘, ‘o‘, ‘n‘] # 创建空列表 empty_list list() # 等价于 []list()的强大之处在于“转换”。当你从函数得到的是一个元组tuple、集合set或者需要把字符串拆成单个字符时list()是你的首选。但请注意如果你只是想要一个包含已知元素的列表直接使用[]在性能和可读性上都更优。第三种列表推导式List Comprehension。# 生成一个1到10的平方数列表 squares [x**2 for x in range(1, 11)] # 结果[1, 4, 9, 16, 25, 36, 49, 64, 81, 100] # 生成一个读书会成员阅读时长超过10小时的名单 members [‘Alice‘, ‘Bob‘, ‘Charlie‘, ‘Diana‘] hours [12, 8, 15, 9] active_members [member for member, hour in zip(members, hours) if hour 10] # 结果[‘Alice‘, ‘Charlie‘]列表推导式是Python的语法糖也是体现其优雅之处的特性之一。它用一行代码完成了一个循环创建和条件筛选的过程。虽然这部分我们后续课程会深入讲但你现在需要知道它的存在。它特别适合从一个现有序列中通过某种规则生成一个新列表的场景代码紧凑且执行效率通常比普通的for循环稍高。第四种使用乘法*操作符进行重复。# 创建一个包含5个0的列表常用于初始化固定长度的计数列表 zero_list [0] * 5 # 结果[0, 0, 0, 0, 0] # 创建一个嵌套列表的“坑” nested [[]] * 3 # 结果[[], [], []]这种方式非常方便但有一个天坑需要特别注意当列表的元素是可变对象如另一个列表、字典时使用*复制的是这个对象的引用而不是创建独立的对象。这意味着nested中的三个子列表实际上是同一个列表对象修改其中任何一个其他两个都会跟着变。这常常是初学者Bug的来源。对于可变对象安全的初始化应该使用列表推导式nested [[] for _ in range(3)]。注意在项目初期如果你不确定优先使用方括号[]创建列表。list()用于转换列表推导式用于复杂生成乘法初始化要警惕可变对象陷阱。2.2 访问元素索引与越界陷阱创建了列表接下来就要从中取数据。访问依赖的是“索引”即元素在列表中的位置编号。正索引与负索引Python的列表索引从0开始这是编程界的通用约定。第一个元素的索引是0第二个是1以此类推。members [‘Alice‘, ‘Bob‘, ‘Charlie‘, ‘Diana‘] print(members[0]) # 输出Alice print(members[2]) # 输出Charlie更妙的是Python支持负索引。-1表示最后一个元素-2表示倒数第二个这在你想获取列表末尾元素时极其方便无需先计算列表长度。print(members[-1]) # 输出Diana print(members[-2]) # 输出Charlie索引越界最常见的错误之一如果你尝试访问一个不存在的索引Python会抛出IndexError。print(members[4]) # IndexError: list index out of range print(members[-5]) # 同样会越界如何避免在访问前尤其是在索引是变量时先判断其是否在有效范围内。可以使用len()函数获取列表长度。index 4 if 0 index len(members): print(members[index]) else: print(f“索引 {index} 超出范围列表长度为 {len(members)}“)在实际脚本编写中更Pythonic的做法是使用异常处理try...except但对于初学者先养成检查的习惯很重要。2.3 修改元素列表的“可变性”体现字符串是不可变的你无法修改字符串中的某个字符。但列表是“可变”数据结构这是它最核心的特性之一。你可以直接通过索引来赋值改变列表中特定位置的元素。members [‘Alice‘, ‘Bob‘, ‘Charlie‘] print(members) # 输出[‘Alice‘, ‘Bob‘, ‘Charlie‘] members[1] ‘Benjamin‘ # 将索引1第二个元素从‘Bob‘改为‘Benjamin‘ print(members) # 输出[‘Alice‘, ‘Benjamin‘, ‘Charlie‘]这个操作是“原地修改”列表对象本身的内存地址没有改变只是其内部的内容发生了变化。理解“可变性”是理解后续所有列表方法如append,insert,remove的基础因为它们大多都是在原列表上直接操作。3. 列表的“灵魂”操作切片如果说索引是“点”那么切片就是“线”和“面”。切片允许你一次性获取列表的一个子序列它是Python序列类型中最强大、最优雅的特性之一。3.1 切片基础语法与三个参数切片的基本语法是list[start:stop:step]。start起始索引包含。默认为0。stop结束索引不包含。默认为列表长度。step步长即每隔几个元素取一个。默认为1。numbers [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] # 获取第2到第5个元素索引1到4不包含索引5 sub1 numbers[1:5] # 结果[1, 2, 3, 4] # 获取前三个元素 sub2 numbers[:3] # 结果[0, 1, 2] # 获取从索引3到末尾的所有元素 sub3 numbers[3:] # 结果[3, 4, 5, 6, 7, 8, 9] # 获取整个列表的副本浅拷贝 sub4 numbers[:] # 结果[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] # 每隔一个元素取一个 sub5 numbers[::2] # 结果[0, 2, 4, 6, 8] # 从后往前取步长为-1即列表反转 reverse_numbers numbers[::-1] # 结果[9, 8, 7, 6, 5, 4, 3, 2, 1, 0] # 从索引8开始往前取到索引2不包含2步长为-2 sub6 numbers[8:2:-2] # 结果[8, 6, 4]关键理解stop索引指向的元素是取不到的。记住一个口诀“顾头不顾尾”。numbers[1:5]获取的是索引为1, 2, 3, 4的元素。这种设计避免了在计算范围时出现“差一错误”。3.2 切片的高级应用与内存视图切片操作返回的是原列表的一个新列表但这里有一个非常重要的细节对于列表中的不可变元素如整数、字符串切片是创建了一份独立的拷贝然而对于嵌套的可变对象情况会复杂一些这涉及到“浅拷贝”概念后续课程会深入。切片的一个强大应用是原地修改列表的某个区间。data [‘a‘, ‘b‘, ‘c‘, ‘d‘, ‘e‘, ‘f‘] data[1:4] [‘x‘, ‘y‘, ‘z‘] # 将索引1到3的元素替换为新列表 print(data) # 输出[‘a‘, ‘x‘, ‘y‘, ‘z‘, ‘e‘, ‘f‘] # 甚至可以替换为长度不同的列表 data[1:4] [‘only_one‘] # 用单个元素替换一个区间 print(data) # 输出[‘a‘, ‘only_one‘, ‘e‘, ‘f‘]这个特性让你可以非常灵活地批量更新列表内容而无需编写复杂的循环。3.3 切片与循环的搭配高效数据处理在处理数据时我们经常需要按块处理。例如有一个包含100个用户ID的列表你想每次处理10个。all_user_ids list(range(100)) # 假设是0到99的ID batch_size 10 for i in range(0, len(all_user_ids), batch_size): batch all_user_ids[i:i batch_size] # 关键切片操作 print(f“正在处理批次ID范围{batch}“) # 在这里执行你的处理逻辑比如调用API这段代码中range(0, len(all_user_ids), batch_size)生成了起始索引0, 10, 20, ...。切片all_user_ids[i:i batch_size]则依次取出 [0:10], [10:20], [20:30]... 的子列表。这种模式在数据分批、分页查询等场景中极为常见。4. 列表元素的增删改查实战掌握了创建、访问和切片列表的基本骨架就有了。接下来是让它“动”起来即动态地增加、删除和查找元素。这是列表作为动态数组的核心能力。4.1 增加元素尾部追加与任意位置插入向列表添加元素最常用的两个方法是append()和insert()。append(item)在列表末尾添加一个元素。这是效率最高的添加方式时间复杂度为O(1)。因为它只需要在数组末尾预留的空间里放上新元素。todo_list [‘写博客‘, ‘读文档‘] todo_list.append(‘调试代码‘) print(todo_list) # 输出[‘写博客‘, ‘读文档‘, ‘调试代码‘]append()是“就地修改”直接改变原列表没有返回值返回None。一个常见错误是误以为它有返回值并赋值new_list todo_list.append(‘新任务‘) # 错误append()返回None print(new_list) # 输出None print(todo_list) # 输出[... ‘新任务‘] 原列表已修改insert(index, item)在指定索引位置插入一个元素。这会将原索引位置及之后的元素都向后移动一位因此时间复杂度是O(n)在列表很长且在前部插入时效率较低。todo_list [‘写博客‘, ‘读文档‘, ‘调试代码‘] todo_list.insert(1, ‘开会‘) # 在索引1第二个位置插入 print(todo_list) # 输出[‘写博客‘, ‘开会‘, ‘读文档‘, ‘调试代码‘]当你需要在列表开头插入时insert(0, item)很方便但性能不如append()。如果频繁在开头插入可能需要考虑使用collections.deque双端队列。extend(iterable)批量追加。append()一次加一个extend()则可以将另一个可迭代对象如列表、元组、字符串中的所有元素逐个添加到列表末尾。list_a [1, 2, 3] list_b [4, 5, 6] list_a.extend(list_b) print(list_a) # 输出[1, 2, 3, 4, 5, 6] # 与 运算符效果相同 list_a [7, 8] print(list_a) # 输出[1, 2, 3, 4, 5, 6, 7, 8] # 注意与append的区别 list_c [1, 2] list_c.append([3, 4]) print(list_c) # 输出[1, 2, [3, 4]] 整个列表被当作一个元素添加extend()比用循环逐个append()更简洁效率也通常更高。4.2 删除元素按值、按索引与清空删除同样有多种方式需要根据场景选择。remove(value)删除第一个匹配到的指定值。fruits [‘apple‘, ‘banana‘, ‘orange‘, ‘banana‘] fruits.remove(‘banana‘) print(fruits) # 输出[‘apple‘, ‘orange‘, ‘banana‘]注意它只删除第一个出现的‘banana‘。如果值不存在会引发ValueError。因此安全的做法是先判断if ‘grape‘ in fruits: fruits.remove(‘grape‘)pop([index])删除并返回指定索引的元素。如果不提供索引默认删除并返回最后一个元素栈的“弹出”操作。stack [1, 2, 3, 4, 5] last_item stack.pop() print(last_item) # 输出5 print(stack) # 输出[1, 2, 3, 4] second_item stack.pop(1) # 删除索引1的元素 print(second_item) # 输出2 print(stack) # 输出[1, 3, 4]pop()在你需要同时使用被删除元素的值时非常有用。删除中间元素同样会导致后续元素前移时间复杂度为O(n)。del语句按索引或切片删除。del是Python语句不是列表方法。它可以删除整个列表、列表中的某个元素或一个切片。data [‘a‘, ‘b‘, ‘c‘, ‘d‘, ‘e‘] del data[2] # 删除索引2的元素‘c‘ print(data) # 输出[‘a‘, ‘b‘, ‘d‘, ‘e‘] del data[1:3] # 删除切片[1:3]即索引1和2的元素(‘b‘, ‘d‘) print(data) # 输出[‘a‘, ‘e‘] # del data # 这会删除整个变量data后续再使用data会报错del非常直接但它不返回被删除的值。当你只是想丢弃某些元素而不关心其值时用del很合适。clear()清空列表所有元素。这会将列表重置为空列表[]但列表对象本身仍然存在。temp_data [1, 2, 3, 4, 5] temp_data.clear() print(temp_data) # 输出[]4.3 查找与统计判断存在与计数index(value, [start, [stop]])返回第一个匹配值的索引。colors [‘red‘, ‘green‘, ‘blue‘, ‘green‘, ‘yellow‘] idx colors.index(‘green‘) print(idx) # 输出1 # 可以指定搜索范围 idx2 colors.index(‘green‘, 2) # 从索引2开始找 print(idx2) # 输出3 # 如果找不到会引发ValueError # idx3 colors.index(‘purple‘) # ValueError同样在使用前用in运算符判断是否存在是更稳妥的做法。count(value)统计某个值在列表中出现的次数。scores [85, 90, 85, 78, 90, 85] count_85 scores.count(85) print(count_85) # 输出3in/not in运算符成员关系测试。这是最常用、最高效的查找方式之一用于判断一个元素是否存在于列表中。shopping_list [‘milk‘, ‘eggs‘, ‘bread‘] if ‘eggs‘ in shopping_list: print(“鸡蛋已经在购物清单里了。“) if ‘apple‘ not in shopping_list: print(“还没买苹果。“)in运算符会遍历列表时间复杂度O(n)直到找到目标或遍历完。对于非常大的列表频繁查找效率可能成为瓶颈这时可以考虑使用集合set或字典dict它们基于哈希表查找效率接近O(1)。5. 列表排序、反转与复制让数据井然有序5.1 排序sort()与sorted()的抉择排序是数据处理中的高频操作。Python提供了两种方式它们有本质区别。list.sort(keyNone, reverseFalse)原地排序。这个方法直接修改原列表使其按升序排列。它没有返回值或者说返回None。numbers [3, 1, 4, 1, 5, 9, 2] numbers.sort() print(numbers) # 输出[1, 1, 2, 3, 4, 5, 9] # 降序排序 numbers.sort(reverseTrue) print(numbers) # 输出[9, 5, 4, 3, 2, 1, 1] # 按字符串长度排序 words [‘apple‘, ‘fig‘, ‘banana‘, ‘date‘] words.sort(keylen) # key参数指定一个函数用于提取比较键 print(words) # 输出[‘fig‘, ‘date‘, ‘apple‘, ‘banana‘]key参数非常强大。例如对一个包含元组的列表按元组的第二个元素排序students [(‘Alice‘, 88), (‘Bob‘, 95), (‘Charlie‘, 78)] students.sort(keylambda x: x[1], reverseTrue) # 按分数降序 print(students) # 输出[(‘Bob‘, 95), (‘Alice‘, 88), (‘Charlie‘, 78)]sorted(iterable, keyNone, reverseFalse)返回新列表。这个内置函数接受任何可迭代对象返回一个新的、排序后的列表不改变原对象。original [3, 1, 4, 1, 5] new_sorted_list sorted(original) print(original) # 输出[3, 1, 4, 1, 5] 未改变 print(new_sorted_list) # 输出[1, 1, 3, 4, 5] # 同样支持key和reverse参数 sorted_by_len sorted(words, keylen)如何选择如果你想修改原列表并且不再需要原始顺序用list.sort()它更省内存。如果你想保留原列表或者排序的对象不是列表如元组、字符串用sorted()。一个简单的记忆法sort()是列表的“动作”改变自己sorted()是Python的“函数”给你一个新结果。5.2 反转reverse()与切片[::-1]list.reverse()原地反转列表顺序。nums [1, 2, 3, 4, 5] nums.reverse() print(nums) # 输出[5, 4, 3, 2, 1]使用切片[::-1]创建反转后的新列表。nums [1, 2, 3, 4, 5] reversed_nums nums[::-1] print(nums) # 输出[1, 2, 3, 4, 5] 未变 print(reversed_nums) # 输出[5, 4, 3, 2, 1]选择原则同上想改变原列表用reverse()想得到新列表用切片。5.3 复制浅拷贝与深拷贝的陷阱这是列表操作中最容易出错的地方之一。简单的赋值不会创建列表的副本它只是创建了一个指向同一内存地址的新标签别名。original [[1, 2], [3, 4]] alias original # 这只是起别名 alias[0][0] ‘changed‘ print(original) # 输出[[‘changed‘, 2], [3, 4]]原列表也被改了这显然不是我们想要的。我们需要“拷贝”。浅拷贝 (Shallow Copy)只拷贝第一层。创建浅拷贝有几种方式使用切片[:]。使用list()构造函数。使用copy()方法Python 3.3。import copy original [[1, 2], [3, 4]] shallow_copy original[:] # 或 list(original) 或 original.copy() # 修改第一层原列表不受影响 shallow_copy.append([5, 6]) print(original) # 输出[[1, 2], [3, 4]] print(shallow_copy) # 输出[[1, 2], [3, 4], [5, 6]] # 但是修改第二层嵌套的可变对象原列表依然受影响 shallow_copy[0][0] ‘changed‘ print(original) # 输出[[‘changed‘, 2], [3, 4]]问题出现了 print(shallow_copy) # 输出[[‘changed‘, 2], [3, 4], [5, 6]]浅拷贝创建了一个新列表但新列表中的元素例如[1, 2]这个子列表仍然是原列表中元素的引用。所以修改嵌套对象两边会同步变化。深拷贝 (Deep Copy)递归拷贝所有层级。使用copy模块的deepcopy()函数。import copy original [[1, 2], [3, 4]] deep_copy copy.deepcopy(original) deep_copy[0][0] ‘changed‘ print(original) # 输出[[1, 2], [3, 4]] 完全不受影响 print(deep_copy) # 输出[[‘changed‘, 2], [3, 4]]深拷贝会递归地复制所有嵌套的可变对象创建一个完全独立的副本。代价是如果数据结构非常复杂嵌套很深或很大深拷贝可能比较耗时和耗内存。选择建议如果列表只包含不可变对象数字、字符串、元组浅拷贝就足够了效果和深拷贝一样。如果列表包含其他可变对象列表、字典并且你希望副本完全独立必须使用深拷贝。在不确定的情况下或者数据结构不复杂时使用深拷贝更安全。6. 列表的遍历与性能考量遍历列表是所有操作的基础。最直接的是for循环。6.1 基本遍历for循环fruits [‘apple‘, ‘banana‘, ‘cherry‘] for fruit in fruits: # 直接遍历元素 print(fruit) # 如果需要索引使用 enumerate() for index, fruit in enumerate(fruits): print(f“索引 {index} 的水果是 {fruit}“)enumerate()函数返回一个迭代器每次产生一个(索引, 元素)的元组非常方便。6.2 遍历中的“坑”不要在遍历时修改列表长度这是一个经典错误。如果你在遍历列表的同时又添加或删除了元素可能会导致意想不到的结果甚至程序崩溃。# 错误示例想删除所有偶数 numbers [1, 2, 3, 4, 5, 6] for num in numbers: if num % 2 0: numbers.remove(num) # 在遍历中删除元素 print(numbers) # 输出可能是[1, 3, 5, 6] 为什么6还在因为删除元素后列表长度和索引关系发生了变化迭代器会错乱。正确的做法是创建新列表列表推导式numbers [1, 2, 3, 4, 5, 6] numbers [num for num in numbers if num % 2 ! 0] print(numbers) # 输出[1, 3, 5]遍历副本numbers [1, 2, 3, 4, 5, 6] for num in numbers[:]: # 遍历原列表的切片副本 if num % 2 0: numbers.remove(num) # 修改原列表 print(numbers) # 输出[1, 3, 5]反向遍历适用于删除numbers [1, 2, 3, 4, 5, 6] for i in range(len(numbers)-1, -1, -1): # 从后往前遍历索引 if numbers[i] % 2 0: del numbers[i] print(numbers) # 输出[1, 3, 5]推荐使用第一种创建新列表或第二种遍历副本方法它们更清晰、更安全。6.3 列表与循环的性能列表的查找in、按索引访问list[i]是O(1)操作非常快。但在列表开头或中间插入/删除元素insert,pop(i),remove是O(n)操作因为需要移动后续所有元素。当列表很大比如数十万、百万级元素且需要频繁在非尾部位置增删时列表的性能会成为瓶颈。性能优化小技巧预分配空间如果你事先知道列表的大致长度可以用[None] * size初始化然后通过索引赋值这比反复append()在极大量数据时可能稍快因为避免了多次动态扩容。考虑使用collections.deque如果你需要频繁在列表两端头部和尾部进行添加或删除操作双端队列deque的appendleft()和popleft()操作是O(1)比列表的insert(0, item)和pop(0)O(n)高效得多。成员检查的替代如果需要非常频繁地判断一个元素是否存在于一个集合中且不关心顺序和重复使用set集合的查找效率是O(1)远高于列表的O(n)。7. 列表推导式优雅与效率的典范虽然列表推导式通常被放在更进阶的课程但它的实用性太强值得在这里提前了解其基础。它提供了一种简洁、高效创建列表的方法。7.1 基础语法与转换基本形式[expression for item in iterable]# 将0-9的数字转换为字符串 str_numbers [str(i) for i in range(10)] # 结果[‘0‘, ‘1‘, ‘2‘, ‘3‘, ‘4‘, ‘5‘, ‘6‘, ‘7‘, ‘8‘, ‘9‘] # 计算0-9的平方 squares [x*x for x in range(10)] # 结果[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]它等价于一个for循环squares [] for x in range(10): squares.append(x*x)但列表推导式更简洁并且在CPython解释器中由于其实现方式通常比等效的for循环稍快一些。7.2 带条件的过滤形式[expression for item in iterable if condition]# 获取0-19中所有的偶数 evens [x for x in range(20) if x % 2 0] # 结果[0, 2, 4, 6, 8, 10, 12, 14, 16, 18] # 处理读书会数据筛选阅读时长大于10小时的成员 members [‘Alice‘, ‘Bob‘, ‘Charlie‘, ‘Diana‘] hours [12, 8, 15, 9] active_members [members[i] for i in range(len(members)) if hours[i] 10] # 结果[‘Alice‘, ‘Charlie‘]这里的if是过滤条件只有满足条件的item才会进入表达式计算并加入新列表。7.3 嵌套循环与多重条件列表推导式可以嵌套用于处理更复杂的数据平铺或组合。# 生成一个二维坐标列表 (x, y)其中x和y都在0-2范围内 coords [(x, y) for x in range(3) for y in range(3)] # 结果[(0,0), (0,1), (0,2), (1,0), (1,1), (1,2), (2,0), (2,1), (2,2)] # 等价于嵌套for循环 coords [] for x in range(3): for y in range(3): coords.append((x, y))也可以组合多个if条件。# 生成一个列表包含0-9中能被2或3整除的数 numbers [x for x in range(10) if x % 2 0 or x % 3 0] # 结果[0, 2, 3, 4, 6, 8, 9]使用建议列表推导式让代码更紧凑、更具可读性一旦你熟悉了这种语法。但也要避免过度使用特别是嵌套层数过多或逻辑非常复杂时可能会降低代码的可读性。一个经验法则是如果推导式超过了两行或者包含了复杂的if-else逻辑考虑拆分成普通的for循环可能更清晰。列表是Python编程的基石几乎无处不在。从简单的数据存储到复杂的数据处理流水线列表都扮演着核心角色。理解并熟练运用列表的创建、访问、切片、增删改查、排序遍历以及推导式你就掌握了用Python处理有序数据集合的最重要工具。在后续的课程中我们会将列表与循环、函数、其他数据结构元组、字典、集合结合解决更实际的问题。现在最好的学习方式就是打开你的编辑器把上面的例子都敲一遍然后尝试用列表去整理你手头的一些数据比如管理你的待办事项、记录一周的开销、或者分析一段文本中的单词。实践出真知动手写代码是理解这一切的唯一捷径。
返回列表