跳转至

数据类型

20201129220902

在Python语言中,内置数据类型可大致划分如上

  • 可迭代的,表示一个对象可以用for循环语句迭代其中的每个元素,还可以通过iter()方法转变为迭代器。
  • 可下标的,表示一个对象可以通过下标的方式索引,还可以使用切片功能。
  • 可哈希的,表示一个对象的哈希值在其生命周期内绝不改变。
  • 不可变的,表示一个对象具有固定的值,约等于可哈希。
  • 不重复的,表示一个对象的元素不能相同。

类型判断

  • type()
type(None)  # <class 'NoneType'>
type(True)  # <class 'bool'>

type(123)  # <class 'int'>
type(1.2)  # <class 'float'>
type(1 + 2j)  # <class 'complex'>

type(b'_str')  # <class 'bytes'>
type(_str)  # <class 'str'>

type(_tuple)  # <class 'tuple'>
type(_list)  # <class 'list'>
type(_set)  # <class 'set'>
type(_dict)  # <class 'dict'>
# 直接与list类比较
if type(_list) == list:
    pass

# 转换为字符串后比较
if str(type(_dict)) == "<class 'dict'>":
    pass
  • isinstance()
isinstance(object, object_type)
isinstance(object, (int,float))  # 同时判断是否属于多种类型中的一种

还可以进一步判断是否为可迭代的、可反转的、可哈希的、迭代器、生成器等。

(通常需要引入内置库collections.abc

from collections.abc import Iterable, Reversible, Hashable, Iterator, Generator

_num = 123
_str = "123"
_tuple = (1,2,3)
_list = [1, 2, [31, 32]]
_set = {1,2,3}
_dict = {"a":1,"b":2,"c":3}


# 数值、字符串、元组等不可变的都是可哈希的
print(isinstance(_num, Hashable))  # True
print(isinstance(_str, Hashable))  # True
print(isinstance(_tuple, Hashable))  # True

print(isinstance(_list, Hashable))  # False
print(isinstance(_set, Hashable))  # False
print(isinstance(_dict, Hashable))  # False


# 除了数值型都是可迭代的
print(isinstance(_str, Iterable))  # True
print(isinstance(_tuple, Iterable))  # True
print(isinstance(_list, Iterable))  # True
print(isinstance(_set, Iterable))  # True
print(isinstance(_dict, Iterable))  # True

print(isinstance(_num, Iterable))  # False


# 序列都是可反转的
print(isinstance(_str, Reversible))  # True
print(isinstance(_tuple, Reversible))  # True
print(isinstance(_list, Reversible))  # True

print(isinstance(_num, Reversible))  # False
print(isinstance(_set, Reversible))  # False
print(isinstance(_dict, Reversible))  # False

# 是否为迭代器
isinstance(x, Iterator)

# 是否为生成器
isinstance(x, Generator)

不可迭代的

不可迭代对象均是可哈希的,可以作为dict类型的key,以及set类型的元素。(虽然NoneTrueFalse也是可哈希的,但一般不用作key)

NoneType

只有这一个单例对象:None

Boolean

20201129220346

bool(1)  # True

bool(0)  # False
bool(None)  # False
bool('')  # False

Number

  • 整数 int
# 没有大小限制,inf表示无限大
x = 10  # 默认十进制,10

x = 0b10  # 二进制,2
x = 0o10  # 八进制,8
x = 0x10 # 十六进制,16
  • 浮点数 float

精度默认与其他语言的双精度一样

x = 0.0001
x = 1e-04  # 用科学计数法表示
  • 复数 complex
# 复数由实部和虚部组成,实部和虚部都是浮点型
# 在数学规范中虚部常用i表示,但Python遵循的电气学规范常用j表示
x = 1 + 2j
# 或者complex(real, imag)函数表示
x = complex(1,2)

print(x)  # (1+2j)
print(x.real)  # 打印实部,1.0
print(x.imag)  # 打印虚部,2.0
print(x.conjugate()) # 打印共轭复数(实部相等,虚部相反),(1-2j)

可迭代的

bytes

通常用于网络数据传输、二进制图片和文件的保存等等。

  • 前缀b
_bytes = b''
_bytes = bytes()
_bytes = b'\xe4\xb8\xad\xe6\x96\x87'  # "中文"
_bytes = b'6\xb6a'  # 三个字节:6、\xb6、a

string

_str = ""
_str = "a"
_str = 'abc'  # 单引号
_str = "abc"  # # 双引号
_str = '''abc'''  # 多行字符串
  • 前缀r
# 取消转义,输出原始字符
# 常用于正则表达式,文件路径等地方
x = r'\n'
  • 前缀u
# 表示存储时使用unicode编码
# Py2默认为ascii编码,中文字符前需要加前缀u
# Py3默认为utf_8编码,所以不用加前缀u
x = u'中文'
  • 前缀f
# Py3.6新特性,可以用于格式化字符串
b = "b"
abc = f'a{_str}c'  # "abc"

tuple

元组的存储空间固定,比列表更节省空间,初始化相同元素时元组要快5倍(linux系统),所以若要存储固定的数据,优先考虑使用元组

# 创建空元组
_tuple = ()
# 或者用构造器
_tuple = tuple()

_tuple = ("v",)  # 单元素时需要加逗号,不然会被认为是字符串

_tuple = ("v1", "v2", "v3")
_tuple = "v1", "v2", "v3"  # 可以不带括号

_tuple = ("v1", "v2", ("v3", "v4"))

_tuple = ("v1", "v2", ["v3", "v4"])

_tuple = ("v1", "v2", {"v3":3, "v4":4})

list

# 创建空列表
_list = []
# 或
_list = list()

_list = ["v"]

_list = ["v1", "v2", "v3"]

_list = ["v1", "v2", ("v3", "v4")]

_list = ["v1", "v2", ["v3", "v4"]]

_list = ["v1", "v2", {"v3":3, "v4":4}]

set

集合中的元素必须为可哈希的,即不允许重复元素,所以很适合用于去重以及执行数学上的集合操作如并集、交集、差集和对称差集等。

_set = set()  # 空set,只能用构造器创建
_set = {"k1", "k2", "k3"}

不可变集合:frozenset( )

dict

# 创建空字典
_dict = {}
# 或
_dict = dict()

_dict = {1:"a"}

_dict = {"k1":"v1", "k2":"v2", "k3":"v3"}

# 使用dict()构建字典时,key值不能加引号
_dict = dict(k1="v1", k2="v2")

# 字典的key值只能为可哈希类型
_dict = {("k1", "k2"): "v1"}

# 字典的value值,与列表一样,可以是任意类型
_dict = {"k1":(1,2), "k2":[1,2], "k3":{1,2}, "k4":{"v4": 3}}

推导式

list推导式:[]

[expression for item in iterable]

也可以嵌套循环

# 生成[0x0, 1x1, 2x2, 3x3...]
_list = [i**2 for i in range(5)]  # [0, 1, 4, 9, 16]

# 等价于
_list = []
for i in range(5):
    i = i**2
    _list.append(i)

后面可以跟if条件筛选,但不能带else。

[expression for item in iterable if condition]

# 生成[0x0, 2x2, 4x4...]
_list = [i**2 for i in range(5) if i%2==0]  # [0, 4, 16]

表达式中也可以包含if判断,但必须加else。

[expression if condition else for item in iterable]

_list = [i if i<"b" else i.upper() for i in ["a","b","c"]]  # ['a', 'B', 'C']

可以包含多层循环。一般就两层,内层在前面,外层在后面

[expression for item1 in iterable1 for item2 in iterable2]

_list4 = [x+y for x in ["a","b"] for y in ["A","B"]]  # ['aA', 'aB', 'bA', 'bB']

dict/set推导式:{}

_dict={"a":1, "b":2, "c":3}
# 反转dict的键和值
_tcid = {v:k for k,v in _dict.items()}  # {1: 'a', 2: 'b', 3: 'c'}

# 取dict的键组成一个集合
_k = {k for k,v in _dict.items()}  # {'c', 'a', 'b'}

类型注解

通过类型注解可以提高代码的可读性和易用性

"""
变量类型注解:用 :type 表示
函数返回值类型注解:用 ->type 表示
"""
def func(x:int, y:int) -> int:
    """
    :x:xxx
    :y:xxx
    """
    return x + y

对于复杂的数据结构需要借助 typing 模块来表达这些数据结构

from typing import List, Tuple, Dict

names: List[str] = ['lily', 'tom']
version: Tuple[int, int, int] = (6, 6, 6)
operations: Dict[str, bool] = {'sad': False, 'happy': True}