第3章:数据类型与操作
作为 Java 开发者,你已经熟悉了 Java 的数据类型系统。Python 的数据类型系统更加灵活,本章将详细对比两种语言的数据类型和操作。
3.1 数值类型
Java 数值类型
- 整数类型:byte (1字节), short (2字节), int (4字节), long (8字节)
- 浮点类型:float (4字节), double (8字节)
- BigInteger 和 BigDecimal:用于任意精度的整数和小数
Python 数值类型
- int:任意精度的整数
- float:双精度浮点数
- complex:复数
对比示例:
| 操作 | Java | Python |
|---|---|---|
| 整数定义 | int x = 100; | x = 100 |
| 长整数 | long x = 1000000L; | x = 1000000 (自动处理大整数) |
| 浮点数 | double x = 3.14; | x = 3.14 |
| 科学计数法 | double x = 1.23e-4; | x = 1.23e-4 |
| 复数 | 无内置类型 | x = 1 + 2j |
| 类型转换 | int x = (int) 3.14; | x = int(3.14) |
Python 数值特性:
# 任意精度整数
x = 10**100 # 1后面100个0
print(x) # 正常输出
# 除法总是返回浮点数
print(5 / 2) # 2.5
# 整数除法
print(5 // 2) # 2
# 幂运算
print(2 ** 10) # 1024
# 复数运算
z1 = 1 + 2j
z2 = 3 + 4j
print(z1 + z2) # (4+6j)
print(z1 * z2) # (-5+10j)
3.2 字符串类型
Java 字符串
String类,不可变- 使用
StringBuilder或StringBuffer进行可变字符串操作
Python 字符串
str类型,不可变- 支持多种字符串字面量形式
对比示例:
| 操作 | Java | Python |
|---|---|---|
| 字符串定义 | String s = "Hello"; | s = "Hello" |
| 多行字符串 | String s = """Line1\nLine2"""; | s = '''Line1\nLine2''' |
| 字符串拼接 | s1 + s2 | s1 + s2 |
| 字符串重复 | 需循环实现 | s * 3 |
| 字符串长度 | s.length() | len(s) |
| 字符串切片 | 复杂 | s[0:5] |
| 查找子串 | s.indexOf("ell") | s.find("ell") |
| 替换子串 | s.replace("old", "new") | s.replace("old", "new") |
| 分割字符串 | s.split(",") | s.split(",") |
Python 字符串特性:
# 字符串字面量
str1 = "Hello"
str2 = 'Hello'
str3 = '''Hello
World''' # 多行字符串
# f-string 格式化
name = "Alice"
age = 25
print(f"Name: {name}, Age: {age}")
# 字符串方法
s = " Hello World "
print(s.strip()) # 去除首尾空格
print(s.upper()) # 大写
print(s.lower()) # 小写
print(s.title()) # 首字母大写
# 字符串切片
s = "Python"
print(s[0]) # P
print(s[1:4]) # yth
print(s[::-1]) # nohtyP (反转)
# 字符串判断
print("abc123".isalnum()) # True
print("abc".isalpha()) # True
print("123".isdigit()) # True
3.3 布尔类型
Java 布尔类型
boolean类型,值为true或false- 不能与整数相互转换
Python 布尔类型
bool类型,值为True或False(首字母大写)- 可以与整数相互转换(
True为 1,False为 0)
对比示例:
| 操作 | Java | Python |
|---|---|---|
| 布尔定义 | boolean b = true; | b = True |
| 逻辑与 | a && b | a and b |
| 逻辑或 | a || b | a or b |
| 逻辑非 | !a | not a |
| 与整数转换 | 不允许 | int(True) → 1, bool(0) → False |
| 真值测试 | 基于值 | 基于值(空对象为 False) |
Python 布尔特性:
# 布尔值
print(True) # True
print(False) # False
# 布尔运算
print(True and False) # False
print(True or False) # True
print(not True) # False
# 真值测试
print(bool(0)) # False
print(bool(1)) # True
print(bool("")) # False
print(bool("hello")) # True
print(bool([])) # False
print(bool([1, 2, 3])) # True
# 布尔与整数
print(True + 1) # 2
print(False * 5) # 0
3.4 空值
Java 空值
null关键字- 表示引用类型的空值
Python 空值
None关键字- 表示空值,是一个特殊对象
对比示例:
| 操作 | Java | Python |
|---|---|---|
| 空值定义 | String s = null; | s = None |
| 空值检查 | if (s == null) | if s is None |
| 空值类型 | 引用类型 | NoneType 类型 |
| 空值运算 | 会抛出 NullPointerException | 会抛出 AttributeError |
Python None 特性:
# None 定义
x = None
print(x) # None
print(type(x)) # <class 'NoneType'>
# None 检查
if x is None:
print("x is None")
# None 与其他值比较
print(None == False) # False
print(None == 0) # False
print(None == "") # False
# None 在布尔测试中为 False
print(bool(None)) # False
3.5 列表(类似 Java 数组)
Java 数组
- 固定大小
- 相同类型元素
- 使用下标访问
Python 列表
- 动态大小
- 可以包含不同类型元素
- 使用下标访问,支持切片
对比示例:
| 操作 | Java | Python |
|---|---|---|
| 数组定义 | int[] arr = {1, 2, 3}; | lst = [1, 2, 3] |
| 访问元素 | arr[0] | lst[0] |
| 修改元素 | arr[0] = 10; | lst[0] = 10 |
| 获取长度 | arr.length | len(lst) |
| 添加元素 | 需创建新数组 | lst.append(4) |
| 插入元素 | 需创建新数组 | lst.insert(1, 5) |
| 删除元素 | 需创建新数组 | lst.remove(2) 或 del lst[1] |
| 遍历 | for (int i : arr) | for i in lst |
Python 列表特性:
# 列表定义
lst = [1, 2, 3, "four", 5.5]
# 访问元素
print(lst[0]) # 1
print(lst[-1]) # 5.5 (最后一个元素)
# 切片
print(lst[1:3]) # [2, 3]
print(lst[:2]) # [1, 2]
print(lst[2:]) # [3, "four", 5.5]
# 修改列表
lst.append(6) # 添加到末尾
lst.insert(1, "inserted") # 插入到指定位置
lst.remove(3) # 删除指定值
lst.pop() # 移除并返回最后一个元素
lst.pop(0) # 移除并返回指定位置元素
# 列表方法
lst = [3, 1, 4, 1, 5, 9]
lst.sort() # 排序
print(lst) # [1, 1, 3, 4, 5, 9]
lst.reverse() # 反转
print(lst) # [9, 5, 4, 3, 1, 1]
print(lst.count(1)) # 计算元素出现次数
print(lst.index(4)) # 查找元素位置
# 列表推导式
squares = [x**2 for x in range(10)]
print(squares) # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
3.6 元组(类似 Java 不可变数组)
Java 不可变列表
- 使用
Collections.unmodifiableList() - 或使用 Guava 库的
ImmutableList
Python 元组
- 不可变序列
- 使用圆括号定义
- 支持混合类型
对比示例:
| 操作 | Java | Python |
|---|---|---|
| 不可变列表 | List<Integer> list = Collections.unmodifiableList(Arrays.asList(1, 2, 3)); | tup = (1, 2, 3) |
| 访问元素 | list.get(0) | tup[0] |
| 修改元素 | 不允许 | 不允许 |
| 长度 | list.size() | len(tup) |
| 遍历 | for (int i : list) | for i in tup |
Python 元组特性:
# 元组定义
tup = (1, 2, 3, "four")
# 访问元素
print(tup[0]) # 1
print(tup[-1]) # four
# 切片
print(tup[1:3]) # (2, 3)
# 元组方法
print(tup.count(2)) # 计算元素出现次数
print(tup.index("four")) # 查找元素位置
# 单元素元组
single = (42,) # 注意逗号
# 元组解包
a, b, c = (1, 2, 3)
print(a, b, c) # 1 2 3
# 元组与列表转换
lst = list(tup)
lst.append(5)
tup2 = tuple(lst)
3.7 字典(类似 Java Map)
Java Map
- 接口,常用实现:
HashMap,TreeMap,LinkedHashMap - 键值对存储
- 泛型支持
Python 字典
- 内置类型
dict - 键值对存储
- 动态类型
对比示例:
| 操作 | Java | Python |
|---|---|---|
| 字典定义 | Map<String, Integer> map = new HashMap<>(); | d = {"a": 1, "b": 2} |
| 添加/修改 | map.put("c", 3); | d["c"] = 3 |
| 获取值 | map.get("a") | d["a"] 或 d.get("a") |
| 检查键 | map.containsKey("a") | "a" in d |
| 删除键 | map.remove("a") | del d["a"] 或 d.pop("a") |
| 获取所有键 | map.keySet() | d.keys() |
| 获取所有值 | map.values() | d.values() |
| 获取所有键值对 | map.entrySet() | d.items() |
Python 字典特性:
# 字典定义
d = {"name": "Alice", "age": 25, "city": "New York"}
# 访问值
print(d["name"]) # Alice
print(d.get("age")) # 25
print(d.get("salary", 0)) # 0 (默认值)
# 修改字典
d["age"] = 26 # 修改现有键
d["salary"] = 50000 # 添加新键
# 删除键
del d["city"] # 删除键
print(d.pop("age")) # 移除并返回值
# 字典方法
print(d.keys()) # 所有键
print(d.values()) # 所有值
print(d.items()) # 所有键值对
# 字典遍历
for key in d:
print(key, d[key])
for key, value in d.items():
print(key, value)
# 字典推导式
squares = {x: x**2 for x in range(5)}
print(squares) # {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
# 合并字典
d1 = {"a": 1, "b": 2}
d2 = {"b": 3, "c": 4}
d3 = {**d1, **d2} # Python 3.5+
print(d3) # {"a": 1, "b": 3, "c": 4}
3.8 集合(类似 Java Set)
Java Set
- 接口,常用实现:
HashSet,TreeSet,LinkedHashSet - 不重复元素
- 泛型支持
Python 集合
- 内置类型
set - 不重复元素
- 无序
对比示例:
| 操作 | Java | Python |
|---|---|---|
| 集合定义 | Set<Integer> set = new HashSet<>(); | s = {1, 2, 3} |
| 添加元素 | set.add(4); | s.add(4) |
| 删除元素 | set.remove(2); | s.remove(2) |
| 检查元素 | set.contains(1) | 1 in s |
| 获取大小 | set.size() | len(s) |
| 遍历 | for (int i : set) | for i in s |
| 集合运算 | 使用方法 | 使用操作符 |
Python 集合特性:
# 集合定义
s = {1, 2, 3, 4, 5}
# 添加元素
s.add(6)
# 删除元素
s.remove(3) # 如果元素不存在会抛出异常
s.discard(10) # 如果元素不存在不会抛出异常
# 集合运算
a = {1, 2, 3}
b = {3, 4, 5}
print(a | b) # 并集 {1, 2, 3, 4, 5}
print(a & b) # 交集 {3}
print(a - b) # 差集 {1, 2}
print(a ^ b) # 对称差集 {1, 2, 4, 5}
# 集合方法
print(a.issubset(b)) # a 是否是 b 的子集
print(a.issuperset(b)) # a 是否是 b 的超集
# 集合推导式
even = {x for x in range(10) if x % 2 == 0}
print(even) # {0, 2, 4, 6, 8}
# 空集合
empty_set = set() # 注意:{} 是空字典
3.9 类型转换
Java 类型转换
- 隐式转换:小类型到大类型
- 显式转换:大类型到小类型(需要强制转换)
- 使用包装类进行转换
Python 类型转换
- 使用内置函数进行转换
- 更灵活的类型转换
对比示例:
| 操作 | Java | Python |
|---|---|---|
| 整数转浮点数 | double x = (double) 5; | x = float(5) |
| 浮点数转整数 | int x = (int) 3.9; | x = int(3.9) |
| 字符串转整数 | int x = Integer.parseInt("123"); | x = int("123") |
| 整数转字符串 | String s = String.valueOf(123); | s = str(123) |
| 字符串转浮点数 | double x = Double.parseDouble("3.14"); | x = float("3.14") |
| 列表转字符串 | 需循环构建 | str([1, 2, 3]) |
| 字符串转列表 | 需循环构建 | list("hello") |
Python 类型转换示例:
# 基本类型转换
x = 5
y = float(x) # 5.0
z = str(x) # "5"
# 字符串转换
num_str = "123"
num = int(num_str) # 123
# 列表转换
lst = [1, 2, 3]
lst_str = str(lst) # "[1, 2, 3]"
# 字符串转列表
word = "hello"
char_list = list(word) # ['h', 'e', 'l', 'l', 'o']
# 集合转换
s = {1, 2, 3}
lst = list(s) # [1, 2, 3]
tup = tuple(s) # (1, 2, 3)
# 字典转换
d = {"a": 1, "b": 2}
keys = list(d.keys()) # ["a", "b"]
values = list(d.values()) # [1, 2]
items = list(d.items()) # [("a", 1), ("b", 2)]
3.10 练习
- 数值操作:编写程序,计算两个数的和、差、积、商和余数
- 字符串操作:编写程序,统计字符串中元音字母的个数
- 列表操作:编写程序,将列表中的元素去重
- 字典操作:编写程序,统计字符串中每个字符出现的次数
- 集合操作:编写程序,找出两个列表的交集、并集和差集
- 类型转换:编写程序,将字符串 "123,456,789" 转换为整数列表
3.11 小结
- Python 的数据类型系统比 Java 更灵活,支持动态类型
- Python 的整数没有大小限制,而 Java 有固定的大小
- Python 的字符串操作更丰富,支持切片和 f-string 格式化
- Python 的列表比 Java 数组更强大,支持动态大小和多种操作
- Python 的字典和集合操作更简洁,支持丰富的方法和操作符
- Python 的类型转换更简单,使用内置函数即可
- Python 支持列表推导式、字典推导式等高级特性
通过本章的学习,你已经了解了 Java 和 Python 在数据类型和操作上的主要区别。接下来,我们将学习 Python 的控制流结构。