📢 本文是「Java程序员180天转型AI」系列第6课,建议收藏后阅读
可以随时改大小的"数组"——增删改查、切片、列表推导式▲ Python的列表,就像一把瑞士军刀,灵活又强大
一、开篇:为什么Java程序员需要重新认识"数组" 🎯
在Java里,数组一旦创建,大小就固定了。想动态增删元素?必须用ArrayList。而Python的列表(List)天生就是动态的,不需要区分"数组"和"动态数组"。
今天我们要掌握:
• 列表定义:用方括号 [] 创建• 增删改查:append、insert、pop、remove、索引访问• 列表切片:比Java的subList强大100倍• 列表推导式:Python独有的优雅写法• 对比Java ArrayList:语法差异和性能考量
二、列表定义:比Java的ArrayList更直观 📦
1. 创建列表
# 空列表empty_list = []# 存储同类型数据(和Java ArrayList类似)scores = [85, 92, 78, 96, 88]# 存储不同类型数据(Python特色,Java做不到!)mixed = ["Java程序员", 25, 35000.50, True, None]# 嵌套列表(二维数组)matrix = [ [1, 2, 3], [4, 5, 6], [7, 8, 9]]# 用list()函数转换chars = list("hello") # ['h', 'e', 'l', 'l', 'o']range_list = list(range(5)) # [0, 1, 2, 3, 4]print(type(scores)) # <class 'list'>
💡 Java程序员的感受:• Java:List<Integer> list = new ArrayList<>();• Python:list = []Python不需要泛型!列表可以存任意类型,甚至混合类型。这是灵活性,也是双刃剑——团队协作时建议保持类型一致。
2. 查看列表信息
fruits = ["apple", "banana", "cherry", "date"]# 长度(和Java的size()一样)print(len(fruits)) # 4# 判断元素是否存在(和Java的contains()一样)print("apple" in fruits) # Trueprint("grape" in fruits) # False# 统计出现次数numbers = [1, 2, 2, 3, 2, 4]print(numbers.count(2)) # 3# 查找索引位置print(fruits.index("banana")) # 1# print(fruits.index("grape")) # ❌ ValueError: not in list
三、索引访问:和Java类似,但支持负数索引 🔢
1. 正向索引(和Java一样)
fruits = ["apple", "banana", "cherry", "date", "elderberry"]# 正向索引:从0开始print(fruits[0]) # apple(第一个)print(fruits[1]) # bananaprint(fruits[4]) # elderberry(最后一个)# 越界会报错(和Java的ArrayIndexOutOfBoundsException一样)# print(fruits[10]) # ❌ IndexError: list index out of range
2. 负数索引(Python独有!)
fruits = ["apple", "banana", "cherry", "date", "elderberry"]# 负数索引:从-1开始,倒数print(fruits[-1]) # elderberry(最后一个)print(fruits[-2]) # date(倒数第二个)print(fruits[-5]) # apple(第一个)# 对比Java:获取最后一个元素# Java: fruits.get(fruits.size() - 1)# Python: fruits[-1] ← 简洁太多了!
✅ 负数索引是Python的杀手级特性!Java获取最后一个元素:list.get(list.size() - 1)Python获取最后一个元素:list[-1]代码简洁度直接碾压!
四、增删改查:列表的核心操作 ✏️
1. 增加元素
# append():在末尾添加(和Java的add()一样)fruits = ["apple", "banana"]fruits.append("cherry")print(fruits) # ['apple', 'banana', 'cherry']# insert():在指定位置插入fruits.insert(1, "blueberry") # 在索引1处插入print(fruits) # ['apple', 'blueberry', 'banana', 'cherry']# extend():合并另一个列表(和Java的addAll()一样)more_fruits = ["date", "elderberry"]fruits.extend(more_fruits)print(fruits) # ['apple', 'blueberry', 'banana', 'cherry', 'date', 'elderberry']# + 运算符也可以合并列表combined = [1, 2] + [3, 4] # [1, 2, 3, 4]# * 运算符重复列表repeated = ["hi"] * 3 # ['hi', 'hi', 'hi']
2. 删除元素
fruits = ["apple", "banana", "cherry", "banana", "date"]# pop():删除并返回指定索引的元素(默认最后一个)last = fruits.pop()print(last) # dateprint(fruits) # ['apple', 'banana', 'cherry', 'banana']second = fruits.pop(1) # 删除索引1的元素print(second) # bananaprint(fruits) # ['apple', 'cherry', 'banana']# remove():删除第一个匹配的值fruits.remove("banana")print(fruits) # ['apple', 'cherry']# del 语句:按索引删除del fruits[0]print(fruits) # ['cherry']# clear():清空列表(和Java的clear()一样)fruits.clear()print(fruits) # []
💡 Java程序员的坑:• pop()默认删除最后一个,Java的remove()默认按值删除• remove()只删第一个匹配项,想删全部要用循环或列表推导式• del是Python语句不是方法,语法是 del list[index]
3. 修改元素
# 直接通过索引赋值(和Java的set()一样)fruits = ["apple", "banana", "cherry"]fruits[1] = "blueberry"print(fruits) # ['apple', 'blueberry', 'cherry']# 批量修改(切片赋值)numbers = [1, 2, 3, 4, 5]numbers[1:3] = [20, 30] # 把索引1到2替换print(numbers) # [1, 20, 30, 4, 5]# 甚至可以替换为不同数量的元素numbers[1:3] = [200, 300, 400]print(numbers) # [1, 200, 300, 400, 4, 5]# 排序(原地排序,和Java的Collections.sort()一样)scores = [85, 92, 78, 96, 88]scores.sort()print(scores) # [78, 85, 88, 92, 96]# 降序排序scores.sort(reverse=True)print(scores) # [96, 92, 88, 85, 78]# 反转(和Java的Collections.reverse()一样)scores.reverse()print(scores) # [78, 85, 88, 92, 96]
五、列表切片:Python最强大的特性之一 🔪
1. 基本切片语法
# 切片语法:list[start:end:step]# start:起始索引(包含)# end:结束索引(不包含)# step:步长(默认1)numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]# 取索引2到5(不包含5)print(numbers[2:5]) # [2, 3, 4]# 从开头取到索引5print(numbers[:5]) # [0, 1, 2, 3, 4]# 从索引5取到末尾print(numbers[5:]) # [5, 6, 7, 8, 9]# 取全部(复制列表)print(numbers[:]) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]# 负数索引切片print(numbers[-3:]) # [7, 8, 9](最后3个)print(numbers[:-3]) # [0, 1, 2, 3, 4, 5, 6](除最后3个)
2. 步长切片(隔一个取一个)
numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]# 步长为2:取偶数索引print(numbers[::2]) # [0, 2, 4, 6, 8]# 步长为3print(numbers[::3]) # [0, 3, 6, 9]# 步长为-1:反转列表!print(numbers[::-1]) # [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]# 反转后取前3个print(numbers[::-1][:3]) # [9, 8, 7]# 步长为-2:反转后隔一个取print(numbers[::-2]) # [9, 7, 5, 3, 1]# 从索引8倒着取到索引2print(numbers[8:1:-1]) # [8, 7, 6, 5, 4, 3, 2]
✅ 切片是Python的杀手级特性!Java实现同样功能需要写循环或Stream API,Python一行搞定。• 取前3个:list[:3] vs Java的subList(0, 3)• 反转:list[::-1] vs Java的Collections.reverse()• 取偶数位:list[::2] vs Java的复杂Stream操作
3. 切片修改(批量替换/删除)
numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]# 批量替换numbers[2:5] = [200, 300]print(numbers) # [0, 1, 200, 300, 5, 6, 7, 8, 9]# 批量删除(赋值为空列表)numbers = [0, 1, 2, 3, 4, 5]numbers[1:4] = []print(numbers) # [0, 4, 5]# 插入元素(切片位置赋新列表)numbers = [0, 1, 2]numbers[1:1] = [100, 200] # 在索引1处插入print(numbers) # [0, 100, 200, 1, 2]
六、列表推导式:Python最优雅的写法 ✨
1. 基本语法
# 基本语法:[表达式 for 变量 in 可迭代对象]# 示例1:生成1-10的平方数squares = [x**2 for x in range(1, 11)]print(squares) # [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]# 对比Java(需要写循环):# List<Integer> squares = new ArrayList<>();# for (int i = 1; i <= 10; i++) {# squares.add(i * i);# }# 示例2:提取字符串长度names = ["Java", "Python", "Go", "Rust"]lengths = [len(name) for name in names]print(lengths) # [4, 6, 2, 4]
2. 带条件的列表推导式
# 语法:[表达式 for 变量 in 可迭代对象 if 条件]numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]# 只取偶数evens = [x for x in numbers if x % 2 == 0]print(evens) # [2, 4, 6, 8, 10]# 只取大于5的数,并平方result = [x**2 for x in numbers if x > 5]print(result) # [36, 49, 64, 81, 100]# 多重条件filtered = [x for x in range(100) if x % 3 == 0 if x % 5 == 0]print(filtered) # [0, 15, 30, 45, 60, 75, 90](3和5的公倍数)# if-else 在表达式中labels = ["偶数" if x % 2 == 0 else "奇数" for x in range(1, 6)]print(labels) # ['奇数', '偶数', '奇数', '偶数', '奇数']
3. 嵌套列表推导式
# 展平二维列表matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]flat = [x for row in matrix for x in row]print(flat) # [1, 2, 3, 4, 5, 6, 7, 8, 9]# 等价于:# flat = []# for row in matrix:# for x in row:# flat.append(x)# 转置矩阵(行列互换)matrix = [[1, 2, 3], [4, 5, 6]]transposed = [[row[i] for row in matrix] for i in range(3)]print(transposed) # [[1, 4], [2, 5], [3, 6]]
📌 Java程序员的感受:列表推导式 = Java Stream API 的语法糖,但更简洁。Java:list.stream().map(x -> x * x).filter(x -> x > 10).collect(Collectors.toList())Python:[x**2 for x in list if x**2 > 10]但注意:列表推导式会一次性生成所有数据,大数据量时用生成器表达式(后面讲)。
七、列表遍历:比Java的for-each更灵活 🔄
fruits = ["apple", "banana", "cherry"]# 方式1:直接遍历(和Java的for-each一样)for fruit in fruits: print(fruit)# 方式2:带索引遍历(和Java的for-i一样)for i in range(len(fruits)): print(f"{i}: {fruits[i]}")# 方式3:enumerate()(Python推荐!)for index, fruit in enumerate(fruits): print(f"{index}: {fruit}")# 从1开始计数for index, fruit in enumerate(fruits, start=1): print(f"{index}. {fruit}")# 方式4:同时遍历多个列表(zip)names = ["Alice", "Bob", "Charlie"]<nages = [25, 30, 35]for name, age in zip(names, ages): print(f"{name} is {age} years old")# 方式5:反向遍历for fruit in reversed(fruits): print(fruit)# 方式6:排序后遍历(不改变原列表)scores = [85, 92, 78, 96]for score in sorted(scores): print(score) # 78, 85, 92, 96print(scores) # [85, 92, 78, 96](原列表不变)
✅ enumerate()是Python的神器!Java获取索引和值:for (int i = 0; i < list.size(); i++) { ... }Python获取索引和值:for i, val in enumerate(list): ...代码量直接减半!
八、综合对比:Java ArrayList vs Python List 📊
| 操作 | Java ArrayList | Python List |
|---|---|---|
九、今日实战:Java程序员技能评分系统 🎯
# Java程序员AI转型 - 技能评分系统print("=" * 50)print("📊 Java程序员技能自评系统")print("=" * 50)# 技能列表skills = [ "Java基础", "Spring框架", "MySQL", "Python基础", "机器学习", "深度学习", "数据分析", "NLP", "计算机视觉"]# 模拟评分(1-10分)import randomscores = [random.randint(1, 10) for _ in skills]print(" 📝 您的技能评分:")for i, (skill, score) in enumerate(zip(skills, scores), 1): bar = "█" * score + "░" * (10 - score) print(f"{i:2d}. {skill:12s} {bar} {score}分")# 统计java_skills = scores[:4] # Java相关技能ai_skills = scores[4:] # AI相关技能print(f" 📈 统计结果:")print(f"Java技能平均分:{sum(java_skills)/len(java_skills):.1f}")print(f"AI技能平均分:{sum(ai_skills)/len(ai_skills):.1f}")# 找出最强和最弱技能max_score = max(scores)min_score = min(scores)max_index = scores.index(max_score)min_index = scores.index(min_score)print(f" 🏆 最强技能:{skills[max_index]} ({max_score}分)")print(f"💪 最弱技能:{skills[min_index]} ({min_score}分)")# 筛选需要加强的技能(低于6分)weak_skills = [skills[i] for i, s in enumerate(scores) if s < 6]if weak_skills: print(f" ⚠️ 需要加强的技能:{', '.join(weak_skills)}")else: print(" 🎉 所有技能都在及格线以上!")# 技能提升建议ai_avg = sum(ai_skills) / len(ai_skills)if ai_avg < 5: print(" 🎯 建议:重点学习机器学习和深度学习基础")elif ai_avg < 7: print(" 🎯 建议:加强实战项目经验")else: print(" 🎯 建议:可以开始投AI岗位简历了!")print("=" * 50)
✅ 这个练习涵盖了今天所有知识点:• 列表创建和索引访问• 切片操作(scores[:4], scores[4:])• 列表推导式(random.randint + for _ in)• enumerate()遍历• zip()并行遍历• 条件筛选推导式• max/min/sum/len等内置函数
十、今日任务 & 明天预告 🚀
📌 今日任务(完成来打卡)
✅ 用PyCharm运行今天的技能评分系统,修改技能列表和评分逻辑✅ 练习列表切片:尝试各种[start:end:step]组合✅ 写5个不同的列表推导式,覆盖带条件和嵌套场景✅ 对比Java ArrayList和Python List的语法差异
📌 明天(第7课)预告
字典(Dict)—— 像HashMap一样用
我们会聊:• 字典的定义和基本操作(增删改查)• 键值对遍历(keys/values/items)• 字典推导式(和列表推导式类似)• 字典 vs Java HashMap的对比• 实际场景:JSON数据处理、配置管理
📌 所有软件和后续代码流程都免费分享,有需要关注后留言即可。本节课程源码已经放在老位置了,刷新后即可获取!建议将我设为星标,避免错过每日课程。坚持180节课,预祝我们转型成功!
如果这篇文章对你有帮助,欢迎点赞、收藏、转发给身边的Java同行。明天见!👋
夜雨聆风