【Day02 Java转Python】Python的ArrayList: list与tuple的“双面人生

容器类型(一):列表与元组

如果你是从Java转向Python的开发者,看到listtuple,第一反应很可能是:"这不就是ArrayList和不可变数组吗?" 没错,这个直觉非常准。但Python的列表和元组比Java的对应物更灵活、语法更简洁,甚至能让你写出"一行顶十行"的代码。

本文将带你深入理解Python中的这对"双面兄弟"------可变与不可变、动态与静态、丰富操作与严格约束,并通过与Java的对比,让你快速掌握它们的用法和适用场景。


一、list:Python 的"超级 ArrayList"

Java中的ArrayList是使用最广泛的动态数组,而Python的list就是它的"增强版"------不仅支持所有ArrayList的操作,还提供了切片、列表推导等杀手级特性。

1.1 创建与基本操作

python 复制代码
# 创建列表
fruits = ["apple", "banana", "cherry"]
numbers = [1, 2, 3, 4, 5]
mixed = [1, "hello", 3.14, True]   # Python列表可混合类型

# 增
fruits.append("orange")          # 末尾追加
fruits.insert(1, "grape")        # 指定位置插入
fruits.extend(["melon", "kiwi"]) # 合并另一个列表

# 删
fruits.remove("banana")          # 删除指定值(只删第一个)
popped = fruits.pop()            # 弹出末尾元素
del fruits[0]                    # 删除索引位置元素
fruits.clear()                   # 清空列表

# 改
fruits[0] = "blueberry"          # 直接赋值修改

# 查
print(fruits[2])                 # 索引访问
print(fruits[-1])                # 倒数第一个
print(fruits.index("cherry"))    # 查找索引
print("apple" in fruits)         # 成员判断

与Java对比:

操作 Java ArrayList Python list
追加 add(e) append(e)
插入 add(i, e) insert(i, e)
删除值 remove(o) remove(o)
删除索引 remove(i) pop(i)del lst[i]
长度 size() len(lst)
判空 isEmpty() not lstlen(lst)==0

Python胜在语法统一len()适用于所有容器,in操作符简洁直观。

1.2 切片:list 的"手术刀"

切片是Python最强大的特性之一,一次操作就能完成子数组的提取、复制、甚至原地替换。Java中需要循环或subList,而Python一行搞定。

python 复制代码
nums = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

# 获取子列表 [2, 3, 4]
sub = nums[2:5]          # 起始索引:结束索引(不包含结束)

# 从开头到索引5(不含)
head = nums[:5]          # [0,1,2,3,4]

# 从索引5到末尾
tail = nums[5:]          # [5,6,7,8,9]

# 步长(每2个取1个)
every_second = nums[::2] # [0,2,4,6,8]

# 反转列表
reversed_nums = nums[::-1]  # [9,8,7,...,0]

# 复制列表(浅拷贝)
copy = nums[:]           # 等价于 nums.copy()

高级玩法:切片赋值

python 复制代码
nums = [0, 1, 2, 3, 4]
nums[1:3] = [10, 20, 30]   # 替换索引1~2为三个元素
print(nums)                # [0, 10, 20, 30, 3, 4]

nums[2:4] = []             # 删除索引2~3的元素
print(nums)                # [0, 10, 4]

这种原地修改的能力是Java ArrayList难以企及的。

1.3 列表推导式:声明式编程的典范

列表推导式(list comprehension)是Python独有的语法糖,它将循环和条件判断压缩进一个表达式,生成新列表。对于Java开发者来说,它相当于Stream API的简化版。

基础语法[表达式 for 变量 in 可迭代对象 if 条件]

python 复制代码
# 生成平方数列表
squares = [x**2 for x in range(10)]
# Java: IntStream.range(0,10).map(x -> x*x).boxed().collect(Collectors.toList())

# 带条件的过滤
even_squares = [x**2 for x in range(10) if x % 2 == 0]

# 嵌套循环(生成坐标对)
coords = [(x, y) for x in range(3) for y in range(3)]
# [(0,0),(0,1),(0,2),(1,0),...]

# 条件表达式(三元)
results = [x if x > 0 else 0 for x in [-1, 2, -3, 4]]

与Java的Stream对比:

功能 Java Stream Python列表推导
map .map(f) [f(x) for x in list]
filter .filter(p) [x for x in list if p(x)]
flatMap .flatMap(f) [y for x in list for y in f(x)]

列表推导式更紧凑、更易读(对Python程序员而言)。而且由于是立即执行,不需要终端操作。

1.4 其他常用方法

python 复制代码
nums = [3, 1, 4, 1, 5, 9, 2]
nums.sort()              # 原地排序
sorted_nums = sorted(nums)  # 返回新列表,原列表不变
nums.reverse()           # 原地反转
print(sum(nums))         # 求和
print(max(nums), min(nums))
print(nums.count(1))     # 统计出现次数

二、tuple:不可变的"定海神针"

元组(tuple)与列表几乎一模一样,除了一个关键区别:不可变。一旦创建,不能增、删、改。这让它天然具备哈希能力,可以作为字典的键,也是函数多返回值的不二之选。

2.1 创建与访问

python 复制代码
# 创建元组
point = (10, 20)
single = (5,)            # 只有一个元素时必须有逗号
empty = ()

# 访问(与列表相同)
print(point[0])          # 10
print(point[-1])         # 20

# 不可变性演示
point[0] = 30            # TypeError: 'tuple' object does not support item assignment

2.2 元组的不可变 ≠ 内容不可变

注意:如果元组内包含可变对象(如列表),该对象本身可以改变。元组只是"引用"不可变。

python 复制代码
t = (1, 2, [3, 4])
t[2].append(5)           # 合法!列表内容改变了
print(t)                 # (1, 2, [3, 4, 5])
# t[2] = [6,7]           # 错误!不能更换引用

这一点和Java中final修饰的引用类型变量类似。

2.3 元组的常用操作

由于不可变,元组的方法很少:count(计数)、index(查找索引)。但许多列表的操作(如lenin、切片)同样适用于元组。

python 复制代码
t = (1, 2, 3, 2, 2)
print(t.count(2))        # 3
print(t.index(3))        # 2
print(t[1:3])            # (2, 3) 切片返回新元组

2.4 元组的解包(Unpacking)------ Python的优雅之处

元组最实用的功能之一是解包,尤其适合函数返回多个值。

python 复制代码
# 简单解包
a, b = (10, 20)

# 交换变量(无需临时变量)
x, y = y, x

# 函数返回多个值
def get_user():
    return "Alice", 25

name, age = get_user()
print(name, age)

# 带星号收集剩余元素
first, *rest = (1, 2, 3, 4)   # first=1, rest=[2,3,4]

Java中返回多值通常需要自定义类或Pair/Tuple库,而Python原生支持。

2.5 元组作为字典的键

由于元组是不可变的,它可以作为字典的键,而列表不行。

python 复制代码
locations = {}
locations[(35.68, 139.76)] = "Tokyo"   # 经纬度元组作为键
# locations[[1,2]] = "error"           # 报错:unhashable type: 'list'

三、list vs tuple:如何选择?

场景 推荐 原因
元素数量会变化 list 可变,增删改方便
需要作为字典的键 tuple 不可变,可哈希
函数返回多个值 tuple 轻量、解包方便
存储同质数据(如所有整数) list 通常需要修改或扩展
配置常量(如颜色RGB值) tuple 语义上不应改变
性能要求高且数据固定 tuple 创建速度略快,内存占用更小

性能小贴士:在相同数据量下,元组的创建速度比列表快约10~30%,内存占用也更少。但如果数据频繁修改,列表更合适。


四、与Java的思维转换总结

概念 Java Python
动态数组 ArrayList<E> list(混合类型)
不可变列表 List.of(...) 返回不可变List tuple
子数组/切片 list.subList(from, to) lst[start:end]
复制列表 new ArrayList<>(list) lst[:]lst.copy()
列表推导 Stream API + collector [expr for x in list]
多返回值 自定义类或Object[] (a, b) 元组+解包
交换变量 临时变量 a, b = b, a

Python的哲学:简洁优于复杂,直接优于间接。当你熟练使用切片和列表推导后,会发现很多原本需要循环的代码都可以被一行取代。


五、动手练习:巩固你的理解

尝试用Python实现以下任务,并思考如果用Java会怎么写:

  1. 给定一个列表nums = [1,2,3,4,5,6],取出所有奇数,并计算它们的平方,生成新列表。
  2. 交换列表中的第一个和最后一个元素。
  3. 将两个列表keys = ["name", "age"]values = ["Alice", 25]合并成一个字典。
  4. 编写一个函数,接受任意多个参数,返回它们的和与平均值(用元组返回)。

参考解答

python 复制代码
# 1
nums = [1,2,3,4,5,6]
result = [x**2 for x in nums if x % 2 == 1]   # [1, 9, 25]

# 2
nums[0], nums[-1] = nums[-1], nums[0]

# 3
d = dict(zip(keys, values))   # {'name': 'Alice', 'age': 25}

# 4
def stats(*args):
    total = sum(args)
    avg = total / len(args)
    return total, avg

Python的listtuple虽然简单,却是日常编程中使用频率最高的数据结构。理解它们的特性,尤其是切片和推导式,能让你写出更Pythonic的代码。下一篇文章我们将继续探讨Python的其他容器类型:dictset,敬请期待!

当你开始习惯用一行列表推导代替四五行循环,用元组解包优雅地交换变量,你会感受到Python设计的精妙------让程序员专注于业务逻辑,而非繁琐的语法。

相关推荐
itzixiao21 小时前
L1-051 打折(5分)[java][python]
java·python·算法
HappyAcmen1 天前
10.常见报错排查与基础调试
开发语言·python
山川而川-R1 天前
Windows新系统_安装anaconda-2026-4.24
python
それども1 天前
Spring Bean 注入的优先级顺序
java·数据库·sql·spring
ID_180079054731 天前
Python 实现京东商品详情 API 数据准确性校验(极简可直接用)
java·前端·python
贾斯汀玛尔斯1 天前
每天学一个算法--Aho–Corasick 自动机
java·linux·算法
码农的神经元1 天前
配电网智能决策平台:从风险感知到自愈控制的 Python 实现
开发语言·python
LF男男1 天前
Action- C# 内置的委托类型
java·开发语言·c#
zhaoshuzhaoshu1 天前
主流 AI 编程助手工具特点与对比
人工智能·python
Daydream.V1 天前
Python 多线程编程从入门到精通:基础 + 实战 + 避坑全攻略
python·线程·threading·线程教学