Python(五):第四章:类型转换详解

第四章:类型转换详解

4.1 基本数据类型转换

整型转换 int()

最常用的一种转换类型,通过 int() 可以实现进制之间的快速转换,而无需调用函数

1
2
3
4
5
6
7
8
9
10
11
12
13
# 基本转换
int(3.14) # 3 (截断小数部分,不是四舍五入)
int(-3.9) # -3 (向零截断)
int("42") # 42 (字符串必须表示有效的数字)
int("0xFF", 16) # 255 (可以指定进制,默认为10进制)
int("101", 2) # 5 (二进制转十进制)
int(True) # 1
int(False) # 0

# 转换失败的情况
# int("3.14") # ValueError: invalid literal for int() with base 10
# int("hello") # ValueError: invalid literal for int() with base 10
# int([1, 2]) # TypeError: int() argument must be a string, a bytes-like object or a real number

浮点型转换 float()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 基本转换
float(42) # 42.0
float("3.14") # 3.14
float("42") # 42.0
float("-3.14e2")# -314.0 (支持科学计数法)
float("inf") # inf (无穷大)
float("-inf") # -inf (负无穷大)
float("nan") # nan (非数值)
float(True) # 1.0
float(False) # 0.0

# 转换失败的情况
# float("hello") # ValueError: could not convert string to float: 'hello'
# float([1, 2]) # TypeError: float() argument must be a string or a real number

字符串转换 str()

1
2
3
4
5
6
7
# 基本转换 - 几乎任何Python对象都可以转为字符串
str(42) # '42'
str(3.14) # '3.14'
str(True) # 'True'
str([1, 2, 3]) # '[1, 2, 3]'
str({'name': 'John'}) # "{'name': 'John'}"
str(None) # 'None'

布尔值转换 bool()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 基本转换规则:空值或零值转为False,其他为True
bool(0) # False
bool(0.0) # False
bool("") # False
bool([]) # False
bool({}) # False
bool(set()) # False
bool(()) # False
bool(None) # False

bool(1) # True
bool(-1) # True
bool(0.1) # True
bool("hello") # True
bool([0]) # True
bool({0: 0}) # True

4.2 集合类型转换

列表转换 list()

1
2
3
4
5
6
# 从其他可迭代对象创建列表
list("hello") # ['h', 'e', 'l', 'l', 'o']
list((1, 2, 3)) # [1, 2, 3]
list({1, 2, 3}) # [1, 2, 3] (集合转列表,顺序不确定)
list({"a": 1, "b": 2}) # ['a', 'b'] (字典转列表,获取所有键)
list(range(5)) # [0, 1, 2, 3, 4]

元组转换 tuple()

1
2
3
4
5
6
7
8
9
# 从其他可迭代对象创建元组
tuple([1, 2, 3]) # (1, 2, 3)
tuple("hello") # ('h', 'e', 'l', 'l', 'o')
tuple({1, 2, 3}) # (1, 2, 3) (集合转元组,顺序不确定)
tuple({"a": 1, "b": 2}) # ('a', 'b') (字典转元组,获取所有键)

# 特殊情况:创建空元组和单元素元组
empty_tuple = ()
single_element_tuple = (42,) # 注意逗号是必需的

集合转换 set()

1
2
3
4
5
6
7
8
9
10
11
# 从其他可迭代对象创建集合(自动去重)
set([1, 2, 2, 3, 3, 3]) # {1, 2, 3}
set("hello") # {'h', 'e', 'l', 'o'}
set((1, 2, 2, 3)) # {1, 2, 3}
set({"a": 1, "b": 2}) # {'a', 'b'} (字典转集合,获取所有键)

# 应用:列表去重
unique_items = list(set([1, 2, 2, 3, 3, 3])) # [1, 2, 3] (顺序可能变化)

# 创建空集合
empty_set = set() # 不能用{},那会创建空字典

字典转换 dict()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 从键值对创建字典
dict([('a', 1), ('b', 2)]) # {'a': 1, 'b': 2}

# 从两个等长序列创建字典
keys = ['a', 'b', 'c']
values = [1, 2, 3]
dict(zip(keys, values)) # {'a': 1, 'b': 2, 'c': 3}

# 使用关键字参数创建字典
dict(a=1, b=2, c=3) # {'a': 1, 'b': 2, 'c': 3}

# 合并两个字典 (Python 3.9+)
dict1 = {'a': 1, 'b': 2}
dict2 = {'c': 3, 'd': 4}
dict1 | dict2 # {'a': 1, 'b': 2, 'c': 3, 'd': 4}

4.3 进阶类型转换

字节转换 bytes()bytearray()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 字符串转字节
bytes("hello", "utf-8") # b'hello'
bytes("你好", "utf-8") # b'\xe4\xbd\xa0\xe5\xa5\xbd'

# 整数列表转字节
bytes([65, 66, 67]) # b'ABC'

# 创建指定长度的空字节序列
bytes(5) # b'\x00\x00\x00\x00\x00'

# bytearray是可变版本的bytes
ba = bytearray("hello", "utf-8") # bytearray(b'hello')
ba[0] = 72 # 修改第一个字节为'H'
print(ba) # bytearray(b'Hello')

# 字节转回字符串
b"hello".decode("utf-8") # 'hello'
bytearray(b"hello").decode("utf-8") # 'hello'

4.4 实用转换场景与技巧

数字和字符串之间的转换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 格式化数字为字符串
str(1234) # '1234'
"{:,}".format(1234567.89) # '1,234,567.89' (添加千位分隔符)
"{:.2f}".format(3.14159) # '3.14' (保留2位小数)
f"{123.456:.2e}" # '1.23e+02' (科学计数法)

# 解析数字字符串
int("1234") # 1234
float("3.14") # 3.14
float("1.23e45") # 1.23e+45

# 处理货币字符串
price = "$1,234.56"
float(price.replace("$", "").replace(",", "")) # 1234.56

数据类型检测与安全转换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 安全地转换为整数
def safe_int(value,default=0):
try:
return int(value)
except (ValueError,TypeError):
return default


print(safe_int("123")) # 123
print(safe_int("abc")) # 0
print(safe_int(None)) # 0
print(safe_int("456", 100)) # 456
print(safe_int("xyz", 100)) # 100

#================================================================================================

类型转换与数据验证

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# 验证并转换输入数据
def validate_age(age_str):
try:
age = int(age_str) # 尝试将字符串转换为整数
if 0 <= age <= 120: # 验证年龄是否在0到120之间
return age # 若年龄有效,则返回年龄
else:
raise ValueError("年龄必须在0到120之间") # 若年龄无效,则抛出异常
except ValueError:
raise ValueError("无效的年龄格式") # 若输入的年龄不是整数,则抛出异常

# 适用于表单验证
def validate_form(form_data):
errors = {}

# 验证和转换名称
name = form_data.get("name","").strip()
if not name:
errors["name"] = "请输入姓名"

#验证和转换年龄
age_str = form_data.get("age","")
try:
age = validate_age(age_str)
except ValueError as e:
errors["age"] = str(e) # 把异常信息转换为字符串
return errors or None # 如果errors为空,则返回None,否则返回errors

# 测试
form_data = {
"name": "张三",
"age": ""
}
print(validate_form(form_data)) # 输出:{'age': '无效的年龄格式'}

4.5 类型转换陷阱与最佳实践

常见陷阱

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 1. 精度损失
int(3.99999) # 3 (信息丢失)

# 2. 截断而非四舍五入
int(3.6) # 3 (很多新手误以为会四舍五入)

# 3. 不安全的eval
user_input = "1 + 1"
eval(user_input) # 2 (安全)

user_input = "__import__('os').system('rm -rf 防止手残')"
# eval(user_input) # 危险!可以执行任意代码,执行rm -rf / 会导致整个系统被删除

# 4. 大数字字符串转换性能问题
very_large_num = "9" * 1000000
# int(very_large_num) # 会很慢并占用大量内存

# 5. 浮点数精度问题
float("0.1") + float("0.2") != float("0.3") # True,因为浮点精度问题