为什么说Python的数据结构是杀手锏?
Java程序员最常用的集合类:ArrayList、HashMap、HashSet。Python也有对应的list、dict、set,但用起来爽太多了。
原因是Python把这些数据结构做成了语言内置的语法,而不是像Java那样只是库里的类。
一、列表(list):比ArrayList强在哪?
基本操作
# 创建
fruits = ["苹果", "香蕉", "橘子"]
访问(和Java一样从0开始)
first = fruits[0] # "苹果"
修改
fruits[1] = "草莓"
长度
print(len(fruits)) # 3
添加
fruits.append("西瓜") # 末尾添加
fruits.insert(1, "葡萄") # 指定位置插入
删除
fruits.remove("香蕉") # 按值删除
popped = fruits.pop() # 弹出最后一个
骚操作:切片(Slice)
这是Java没有的。切片可以让你用一行代码完成Java要写一个循环才能做的事:
nums = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
取前3个
first_three = nums[:3] # [0, 1, 2]
取后3个
last_three = nums[-3:] # [7, 8, 9]
从第2个到第5个
middle = nums[2:5] # [2, 3, 4]
每隔2个取一个
every_other = nums[::2] # [0, 2, 4, 6, 8]
反转
reversed_list = nums[::-1] # [9, 8, 7, ..., 0]
切片赋值(Java想都别想)
nums[2:5] = [20, 30, 40] # [0, 1, 20, 30, 40, 5, 6, 7, 8, 9]
Java要实现同样的功能:
List nums = List.of(0,1,2,3,4,5,6,7,8,9);
List firstThree = nums.subList(0, 3);
// 反转?Collections.reverse(nums)...
// 切片赋值?写个循环吧...
列表推导式
一行代码生成一个列表,比Java的Stream还简洁:
# 生成0-99的偶数平方
squares = [x**2 for x in range(100) if x % 2 == 0]
等价的Java代码:
// List squares = IntStream.range(0, 100)
// .filter(x -> x % 2 == 0)
// .map(x -> x * x)
// .boxed()
// .collect(Collectors.toList());
二、字典(dict):比HashMap好用10倍
基本操作
# 创建
user = {
"name": "张三",
"age": 25,
"skills": ["Java", "Python"]
}
访问
name = user["name"] # "张三"
安全访问(不存在返回默认值)
score = user.get("score", 0) # 0
修改
user["age"] = 26
添加
user["email"] = "zhangsan@example.com"
删除
del user["email"]
遍历
for key, value in user.items():
print(f"{key}: {value}")
字典推导式
# 从列表创建字典
names = ["张三", "李四", "王五"]
scores = [90, 85, 95]
grade_book = {name: score for name, score in zip(names, scores)}
{"张三": 90, "李四": 85, "王五": 95}
过滤
passed = {k: v for k, v in grade_book.items() if v >= 90}
{"张三": 90, "王五": 95}
嵌套字典
# 多层嵌套
company = {
"engineering": {
"backend": {"java": 5, "python": 3},
"frontend": {"react": 4, "vue": 2}
},
"product": {
"pm": 3,
"design": 2
}
}
访问嵌套值
java_count = company["engineering"]["backend"]["java"] # 5
Java做同样的事要写多少代码? Map嵌套Map,类型声明一堆,访问时还要各种强制转换。Python一行搞定。
常用技巧
# 合并两个字典
dict1 = {"a": 1, "b": 2}
dict2 = {"b": 3, "c": 4}
merged = {**dict1, **dict2} # {"a": 1, "b": 3, "c": 4}
按值排序
sorted_dict = dict(sorted(grade_book.items(), key=lambda x: x[1], reverse=True))
获取所有key/value
keys = list(user.keys())
values = list(user.values())
三、集合(set):去重和集合运算
# 创建
a = {1, 2, 3, 4}
b = {3, 4, 5, 6}
去重(最常用的场景)
names = ["张三", "李四", "张三", "王五", "李四"]
unique_names = list(set(names)) # ["张三", "李四", "王五"]
集合运算
print(a | b) # 并集: {1, 2, 3, 4, 5, 6}
print(a & b) # 交集: {3, 4}
print(a - b) # 差集: {1, 2}
print(a ^ b) # 对称差集: {1, 2, 5, 6}
判断元素是否存在(O(1)复杂度)
print(3 in a) # True
四、tuple:不可变列表
# tuple创建后不能修改
point = (10, 20)
point[0] = 30 # 报错!
但可以解包
x, y = point
print(x, y) # 10 20
多变量赋值(Python独有)
a, b, c = 1, 2, 3
a, b = b, a # 交换变量,不需要临时变量!
Java交换两个变量要写:
int temp = a;
a = b;
b = temp;
Python一行:
a, b = b, a
五、数据结构选择速查表
| 需求 | Python | Java |
|---|---|---|
| 命名元组 | namedtuple | record (Java 16+) |
总结
Python的数据结构比Java简洁太多,核心原因是:
- 语法内置——list/dict/set直接用语法创建,不需要new
- 切片操作——一行代码完成Java要写循环的事
- 推导式——集合操作的终极简洁写法
- 动态类型——不需要声明泛型参数
下一篇聊Python的函数——lambda、装饰器、闭包,这些才是Python的灵魂。
本系列持续更新中,关注不迷路。