Python3数据类型转换大全
概述
数据类型转换,指的是通过某种方法,将一个数据由原来的类型转换为另外一个类型。比如,我们将字符串“123”转换为数字123,这就是一种数据类型的转换。
Python支持各种标准数据类型之间的转换,但并不是任意数据都可以转换的,所有的转换要符合“常理”,逻辑上应该是成立的。比如,你不应该试图将一个complex类型转换为int,因为python也不知该怎么转换。
数据类型转换支持情况汇总表
| Int | Float | Bool | Complex | String | Bytes | List | Tuple | Set | Dict | |
|---|---|---|---|---|---|---|---|---|---|---|
| Int | - | Y | Y | N | Y | Y | N | N | N | N | 
| Float | Y | - | Y | N | Y | Y | N | N | N | N | 
| Bool | Y | Y | - | Y | Y | Y | Y | Y | Y | Y | 
| Complex | Y | Y | Y | - | Y | N | N | N | N | N | 
| String | Y | Y | Y | Y | - | Y | Y | Y | Y | Y | 
| Bytes | Y | N | Y | N | Y | - | Y | Y | Y | N | 
| List | N | N | N | N | Y | Y | - | Y | Y | Y | 
| Tuple | N | N | N | N | Y | Y | Y | - | Y | Y | 
| Set | N | N | N | N | Y | Y | Y | Y | - | Y | 
| Dict | N | N | N | N | Y | N | Y | Y | Y | - | 
注:Bytes只考虑直接转换的情况
转换实例
转换为int
print(int(1.2))       # float -> int
print(int('123'))     # string -> int
print(int(b'456'))    # bytes -> int
print('0x%x' % (int.from_bytes(b'456', byteorder='little', signed=True)))
print(int(True))      # bool -> int
转换为float
print(float('1.2'))      # string->float
print(float(b'3.4'))     # bytes -> float
print(float(123))        # int->float
print(float(False))      # bool->float
转换为bool
# 所有类型都可以转换为bool型
print(bool(1))           # int->bool
print(bool(0.0))         # float->bool
print(bool(0 + 0j))      # complex->bool
print(bool(''))          # string->bool, 空字符串为False,其它都是True
print(bool(b'hello'))    # bytes->bool, 空为False,其它都是True
print(bool.from_bytes(b'\x00', byteorder='little'))    # bytes->bool
print(bool([]))          # list->bool, 空为False,其它都是True
print(bool(()))          # tuple->bool, 空为False,其它都是True
print(bool({}))          # dict->bool, 空为False,其它都是True
print(bool(set()))       # set->bool, 空为False,其它都是True
转换为complex
print(complex(100))           # int->complex
print(complex(1.2))           # float->complex
print(complex(True))          # bool->complex
print(complex('1.2+2.3j'))    # string->complex
转换为string
# 所有基本类型都可以转换为string
print(b'hello'.decode('utf-8'))       # bytes->string
print(str(1))                         # int->string
print(str(1.2))                       # float->string
print(str(True))                      # bool->string
print(str(1.2 + 2.3j))                # complex->string其它都是True
print(str(['hello', 100]))            # list->string
print(str(('hello', 100)))            # tuple->string
print(str({'name': 'xiaowang', 'age': 20}))    # dict->string
print(str({'name', 'age'}))           # set->string
转换为bytes
# 因为所有类型都可以转换为string,而string可以转换为bytes,所以所有类型都可以间接转换为bytes。
# 下面我们只讨论直接转换为bytes的类型
print('bytes'.center(30, '*'))
print(b'\x64')                              # int转bytes
print(int.to_bytes(100, byteorder='big', signed=True, length=2))      # int转bytes
print(bool.to_bytes(True, byteorder='big', signed=True, length=2))    # bool转bytes
print('hello'.encode(encoding='utf-8'))     # string转bytes
print(bytes([1, 200, 80, 50]))              # list转bytes
print(bytes((1, 200, 80, 50)))              # tuple转bytes
print(bytes({1, 200, 80, 50}))              # set转bytes
转换为list
print(list("hello"))            # string->list
print(list(b'hello'))           # bytes->list
print(list((100, 200, 300)))    # tuple->list
print(list({'name', 'age'}))    # set->list
print(list({'name': 'xiaowang', 'age': 20}))    # dict->list, 只取key值
转换为tuple
print(tuple("hello"))            # string->tuple
print(tuple(b"hello"))           # bytes->tuple
print(tuple([100, 200, 300]))    # list->tuple
print(tuple({'name', 'age'}))    # set->tuple
print(tuple({'name': 'xiaowang', 'age': 20}))   # dict->tuple, 只取key值
转换为set
print(set("hello"))                            # string->set
print(set(b"hello"))                           # bytes->set
print(set([100, 200, 300]))                    # list->set
# print(set([100, 200, [300, 400]]))           # list->set, list中包含可变数据类型,报异常
print(set(('name', 'age')))                    # tuple->set
# print(set(('name', 'age', [])))              # tuple->set,包含可变数据类型,报异常
print(set({'name': 'xiaowang', 'age': 20}))    # dict->set, 只取key值
转换为dict
1、string->dict
# 方式一、使用json转换,字符串格式需要严格按照json格式来
user_str = '{"name": "xiaowang", "city": "Chengdu", "age": 28}'
import json
print(json.loads(user_str))
# 方式二、使用eval函数转换,eval有安全隐患,不建议使用
print(eval(user_str))
# 方式三、 使用ast.literal_eval
import ast
print(ast.literal_eval(user_str))
2、list->dict
# 方式一、需要用到zip
user_keys = ['name', 'city', 'age']
user_values = ['xiaowang', 'Chengdu', 28]
print(dict(zip(user_keys, user_values)))
# 方式二、二维列表
user_info = [
    ["name", "xiaowang"],
    ["city", "Chengdu"],
    ["age", 28]
]
print(dict(user_info))
set->dict tuple->dict的方式和list->dict一样
bytearray ⇋ hex
# hex_str-->bytearray
byte_array = bytearray.fromhex("050460000008d40462000007670463")
print(byte_array)
# bytearray-->hex_str
hex_str = byte_array.hex()
print(hex_str)
以空格分割的hex:
# hex_str-->bytearray
byte_array = bytearray.fromhex("05  04  60  00  00  08  d4  04  62  00  00  07  67  04  63")
print(byte_array)
# bytearray-->hex_str
hex_str = byte_array.hex()
hex_str_space = " ".join([hex_str[i - 1:i + 1] if i % 2 else "" for i in range(len(hex_str))]).strip()
print(hex_str_space)
bytearray ⇋ int
import struct
# int-->bytearray
bytearray_short = struct.pack("<h",666)
print(bytearray_short)
bytearray_int = struct.pack("<i",666)
print(bytearray_int)
bytearray_long = struct.pack("<l",666)
print(bytearray_long)
# bytearray-->int
int_short = struct.unpack("<h",bytearray_short)[0]
print(int_short)
int_int = struct.unpack("<i",bytearray_int)[0]
print(int_int)
int_long = struct.unpack("<l",bytearray_long)[0]
print(int_long)
bytearray ⇋ str
# str-->bytearray
byte_array = bytearray("liuyang", encoding='utf-8')
print(byte_array)
# bytearray-->str
st_r = byte_array.decode('utf-8')
print(st_r)
附录
| 字符 | 字节顺序 | 大小 | 对齐方式 | 
|---|---|---|---|
| @ | 按原字节 | 按原字节 | 按原字节 | 
| = | 按原字节 | 标准 | 无 | 
| < | 小端 | 标准 | 无 | 
| > | 大端 | 标准 | 无 | 
| ! | 网络(=大端) | 标准 | 无 | 
| 格式 | C 类型 | Python 类型 | 标准大小 | 注释 | 
|---|---|---|---|---|
| x | 填充字节 | 无 | ||
| c | char | 长度为 1 的字节串 | 1 | |
| b | signed char | 整数 | 1 | (1), (2) | 
| B | unsigned char | 整数 | 1 | (2) | 
| ? | _Bool | bool | 1 | (1) | 
| h | short | 整数 | 2 | (2) | 
| H | unsigned short | 整数 | 2 | (2) | 
| i | int | 整数 | 4 | (2) | 
| I | unsigned int | 整数 | 4 | (2) | 
| l | long | 整数 | 4 | (2) | 
| L | unsigned long | 整数 | 4 | (2) | 
| q | long long | 整数 | 8 | (2) | 
| Q | unsigned long long | 整数 | 8 | (2) | 
| n | ssize_t | 整数 | (3) | |
| N | size_t | 整数 | (3) | |
| e | (6) | 浮点数 | 2 | (4) | 
| f | float | 浮点数 | 4 | (4) | 
| d | double | 浮点数 | 8 | (4) | 
| s | char[] | 字节串 | ||
| p | char[] | 字节串 | ||
| P | void * | 整数 | (5) | 
- 
'?'转换码对应于 C99 定义的_Bool类型。 如果此类型不可用,则使用char来模拟。 在标准模式下,它总是以一个字节表示。
- 
当尝试使用任何整数转换码打包一个非整数时,如果该非整数具有 __index__()方法,则会在打包之前调用该方法将参数转换为一个整数。在 3.2 版更改: 增加了针对非整数使用 __index__()方法的特性。
- 
'n'和'N'转换码仅对本机大小可用(选择为默认或使用'@'字节顺序字符)。 对于标准大小,你可以使用适合你的应用的任何其他整数格式。
- 
对于 'f','d'和'e'转换码,打包表示形式将使用 IEEE 754 binary32, binary64 或 binary16 格式 (分别对应于'f','d'或'e'),无论平台使用何种浮点格式。
- 
'P'格式字符仅对本机字节顺序可用(选择为默认或使用'@'字节顺序字符)。 字节顺序字符'='选择使用基于主机系统的小端或大端排序。 struct 模块不会将其解读为本机排序,因此'P'格式将不可用。
- 
IEEE 754 binary16 "半精度" 类型是在 IEEE 754 标准 的 2008 修订版中引入的。 它包含一个符号位,5 个指数位和 11 个精度位(明确存储 10 位),可以完全精确地表示大致范围在 6.1e-05和6.5e+04之间的数字。 此类型并不被 C 编译器广泛支持:在一台典型的机器上,可以使用 unsigned short 进行存储,但不会被用于数学运算。 请参阅维基百科页面 half-precision floating-point format 了解详情。
 
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号