python中的数据类型

Python中的数据类型

可变数据类型

对变量的值进行修改时,变量对应的内存地址不变,对应的值发生了改变,这种数据类型就称为可变数据类型。

不可变数据类型

对变量的进行修改时,变量对应的内存地址发生了改变(变量指向了新的内存),从而修改了变量的值,而变量对应的原内存的值并没有被改变,这种数据类型就称为可变数据类型。

也就是:不可变数据类型更改后地址发生改变,可变数据类型更改地址不发生改变

常用数据类型

数据类型 是否是可变数据类型 是否有序
None (空) 不可变 -
int (整数) 不可变 -
float (浮点) 不可变 -
bool (布尔) 不可变 -
str (字符串) 不可变 -
tuple (元组) 不可变 序列类型,有序
list (列表) 可变 序列类型,有序
set (集合) 可变 序列类型,无序,不可重复
dict (字典) 可变 映射类型,v3.6及以后无有序, 前面版本无序

扩展

数据类型 是否是可变数据类型 是否有序 说明
bytes 不可变 - 定义字节:b’hello’,bytes(5)
bytearray 可变 - 定义字节数组:bytearray(b’hello’), bytearray(10)
complex (复数) 不可变 - 由一个实数和一个虚数组合构成,如:4+3j
frozenset (冻结的set) 不可变 无序 冻结的set初始化后不能再添加或删除元素
array (数组) 可变 有序 数组中的元素必须是同一类型
OrderedDict 可变 有序 key有序,setdefault取值key不存在也不报错
defaultdict 可变 有序 取值时Key不存在也不会抛出KeyError异常
deque 可变 有序 高效插入和删除的双向队列列表

常见数据类型的操作和转换

list列表[ ]

list是**==可变====可重复====有序==**列表,里面的元素的数据类型也可以不同(也可以是另一个list)。list可根据索引号取其中的数据。

list的生成

1
2
3
4
5
6
7
8
list1 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
print("list1: ", list(list1)) # 输出: list1: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
list2 = list(range(0, 10))
print("list2: ", list(list2))
list3 = [i*i for i in range(10) if i % 2 == 0]
print("list3: ", list(list3))
list4 = (str(i) + j for i in range(0, 10, 2) for j in "xyz")
print("list4: ", list(list4))

list元素反转、排序和次数统计

1
2
3
4
5
6
7
8
9
10
list1 = [0, 1, 2, 3, 4, 5, 5, 5, 6, 7, 8, 9]

list1.reverse() # 元素顺序反转
print("list reverse: ", list1)
list1.sort(reverse=False) # 排序
print("list sort: ", list1)
list1 = sorted(list1, reverse=True)
print("list sort: ", list1)
times = list1.count(5) # 查看list中的元素出现的次数
print("times: ", times)

list元素的添加、删除和取值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
list1.append(10)
print("append value: ", list1) # 添加元素
list1.insert(1, 10) # 在指定位置添加元素
print("insert value: ", list1)
list1.remove(10) # 删除指定value元素(第一个匹配的元素)
print("remove value: ", list1)
value = list1.pop(12) # 删除指定index的元素并返回删除的值
list1.pop() # 不指定index时默认删除最后一个元素
list1.pop(-2) # 删除倒数第二个元素
print("remove index: ", list1)

index_value = list1.index(3) # 查找第一个value为100的index值,如果不存在报TypeError异常
print("index_value: ", index_value)
print(list1)
index_value = list1.index(5, 7, 9) # 指定范围,从第7(包括)个到第9(不包括)个元素之间查找value为5的index
print("index_value: ", index_value)

list添加多个元素、list的合并

1
2
3
4
5
list2 = [100, 101, 102]
# list1 = list1 + list2
list1.extend(list2)
print(list1)
print("*" * 10)

list的遍历

1
2
3
4
5
6
7
8
9
10
11
for value in list1:
print("value: %i" % value)
print("*" * 50)
for index in range(len(list1)):
print("index: %i, value: %i" % (index, list1[index]))
print("*" * 50)
for index, value in enumerate(list1):
print("index: %i, value: %i" % (index, value))
print("*" * 50)
for index, value in enumerate(list1, 100): # index从100开始
print("index: %i, value: %i" % (index, value))

list中使用切片(slice)取值

1
2
3
4
5
6
7
8
9
10
11
12
13
elements = list1[0:3]  # 取第0到3条元素(包括头不包括尾)
# elements = list1[:3]
print("slice elements: ", elements)
elements = list1[1:] # 取第1到最后一个元素(包括头也包括尾)
print("slice elements: ", elements)
elements = list1[-2] # 取倒数第二条
print("slice elements: ", elements)
elements = list1[4:-2] # 取第四条到倒数第二条(包括头不包括尾)
print("slice elements: ", elements)
elements = list1[0:6:2] # 取第0条到第6条中每2个取一个
print("slice elements: ", elements)
elements = list1[:] # 取所有元素
print("slice elements: ", elements)

==列表、元组和字符串==都可以使用切片进行操作

list的深copy和浅copy

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 浅拷贝只拷贝了引用,没有拷贝内容
list2 = list1
list2[1] = 1000
print("list1: ", list1)
print("list2: ", list1)
print(id(list1), id(list2))

# 深拷贝是对于一个对象所有层次的拷贝(递归拷贝)
list3 = list1.copy()
# import copy
# list3 = copy.copy(list1)
# list3 = copy.deepcopy(list1)
list1[1] = 1
print("list1: ", list1)
print("list3: ", list3)
print(id(list1), id(list3))

set集合{ }

set是**==可变==**、==不可重复==的==无序==列表。 ==set中不可以放入可变对象==,因为无法判断两个可变对象是否相等而去重。

set的定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
set0 = {0, 0, 1, 2, 3, 4, 5, 4, 5, 6}  # 直接定义set集合
print("set0: ", set0) # 输出 set0: {0,1, 2, 3, 4, 5, 6}

set1 = set([0, 0, 1, 2, 3, 4, 5, 4, 5, 6]) # 通过list定义set
print("set1: ", set1)

set2 = set((0, 0, 1, 2, 3, 4, 5, 4, 5, 6)) # 通过tuple定义set
print("set2: ", set2)

set3 = set({"x": 2, 10: "b"}) # 通过dict定义set
print("set3: ", set3) # 输出 set3: {10, 'x'}

my_list = [0, 0, 1, 2, 3, 4, 5, 4, 5]
set4 = set(my_list) # set中不可以放入可变对象,然而为何放入list却不报错?
print("set4: ", set4) # 输出 set4: {0, 1, 2, 3, 4, 5, 6}

# 由下面操作可以得出结论,set是先把list做遍历得到不可变的int对象类型后再放入set中
my_list[0] = 10
print("set4 with my_list changed: ", set4) # 输出 {0, 1, 2, 3, 4, 5, 6}

my_list.append([10, 20])
print("my_list: ", my_list)
set5 = set(my_list) # 在list再放入list,此时将报错
print("set5: ", set5)

set元素的添加、删除和取值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
set0 = {0, 0, 1, 2, 3, 4, 5, 4, 5, 6}
print("set0: ", set0)
set0.add("cn") # 添加单个元素
print("set0: ", set0)

set0.update([10, 20, 30]) # 添加多个元素
print("set0: ", set0)

set0.add(("com", "cn")) # 添加元组(元组是不可变数据类型)
print("set0: ", set0)
# set0.add([10, 20]) # 添加list报错,不能添加可变的数据类型(不能添加,但可以使用list创建set)
# set0.add({10, 20}) # 添加set报错,(可是使用不可变的frozenset添加:set0.add(frozenset({10, 20})))
# set0.add({"x": 2, 10: "b"}) # 添加dict报错,不能添加可变的数据类型(不能添加,但可以使用dict创建set)

set0.remove("cn") # 根据值删除元素(set不能根据索引删除)
print("set0: ", set0)

set取并集和交集

1
2
3
4
5
set1 = {"a", "b", 4, 6, 100}
my_set = set0 | set1 # 取并集
print(my_set)
my_set = set0 & set1 # 取交集
print(my_set)

set遍历

注:set的遍历同list

dict字典{ }

dict是**==无序==,key==不可重复==、==不可变==**内容以key-value键值对形式存在的映射

dict中的key只能是不可变对象且唯一, 一个key对应一个value,多次对一个key设置value,后面的值会把前面的冲掉。

dict一般用在需要高速查找的很多地方。dict的key必须是不可变对象,这是因为dict根据key来计算value的存储位置,如果每次计算相同的key得出的结果不同,那dict内部就完全混乱了。这种通过key计算位置的算法称为哈希算法(Hash)。要保证hash的正确性,作为key的对象就不能变。在Python中,字符串、整数等都是不可变的,因此,可以放心地作为key。而list、set是可变的,所以就不能作为key。

dict的创建和增删改查

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
dict1 = {"addr": "北京", "age": 18, "gender": "女"}
dict1["height"] = 1.77 # 添加元素
dict1.pop("age") # 删除元素输出
item_del = dict1.popitem() # 产出dict中的最后一个item并返回
print("item_del: ", item_del)
dict1["addr"] = "深圳" # 修改元素
print("dict1: ", dict1)

keys = dict1.keys() # 获取dict的所有key
print("keys: ", keys) # dict_keys(['add', 'height'])
addr = dict1.get("addr") # 根据key获取value,若key不存在报异常(defaultdict字典不报异常)
print("addr: ", addr)
addr = dict1.setdefault("addr") # 根据key获取value,若key不存返回None,也可设置默认返回值
print("addr: ", addr)
name = dict1.get("name", "unknow") # 根据key获取value,若key不存返回默认值'unknow'
print("name: ", name)

dict的遍历

1
2
3
4
5
6
7
8
9
10
# dict的遍历
for key in dict1:
print("key: %s, value: %s" % (key, dict1[key]))
print("*" * 50)
for value in dict1.values():
print("value: ", value)
print("*" * 50)

for key, value in dict1.items():
print("key: %s, value: %s" % (key, value))

dict的合并

1
2
3
dict2 = {"mobel": 15888888888, "postal_code": 10000}  # 合并两个dict
dict1.update(dict2)
print("dict1: ", dict1)

dict和list的异同

list查找和插入的时间随着元素的增加而增加;
占用空间小,浪费内存很少

dict查找和插入的速度极快,不会随着key的增加而变慢;
需要占用大量的内存,内存浪费多。
所以,dict是用空间来换取时间的一种方法。

dict的排序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# dict排序
dict3 = {'sh': 3, 'hz': 2, 'tj': 1, 'bj': 5, 'gz': 2, 'sz': 4, 'wh': 1}

# 默认排序,并仅返回key
key_rank1 = sorted(dict3.keys(), reverse=False)
print("key_rank1: ", key_rank1)

# 默认排序(以key来排序),并返回key和value
dict_key_rank1 = sorted(dict3.items(), reverse=False)
print("dict_key_rank1: ", dict(dict_key_rank1))

# 以key排序
dict_key_rank2 = sorted(dict3.items(), key=lambda item: item[0], reverse=False)
print("dict_key_rank2: ", dict(dict_key_rank2))

# 以value排序
dict_value_rank1 = sorted(dict3.items(), key=lambda item: item[1], reverse=False)
print("dict_value_rank1: ", dict(dict_value_rank1))

# 以value排序
dict4 = {'上海': 3, '杭州': 2, '天津': 1, '北京': 5, '广州': 2, '深圳': 4, '武汉': 1}
dict_value_rank2 = sorted(dict4.items(), key=lambda item: item[1], reverse=True)
print("dict_value_rank2: ", dict(dict_value_rank2))

tuple元组( )

tuple是**==不可变====有序==**的列表,所以一般在定义tuple时就进行初始化赋值。

注意:

  • 在定义只有一个元素的tuple时其元素后面要加逗号

    1
    2
    3
    tuple0 = ()  # 创建空元祖
    tuple0 = (1) # 不是tuple,会当成括号处理
    tuple0 = (1,) # 正确的tuple
  • tuple虽然不可变但tuple中的元素对象却是可变的

    1
    2
    3
    4
    5
    my_list = ["x", "y"]
    tuple1 = ('a', 'b', my_list) # tuple包含list,list变化时,tuple1也就跟着变化
    print("tuple1: ", tuple1) # tuple1: ('a', 'b', ['x', 'y'])
    my_list.append("z")
    print("tuple1 with my_list changed: ", tuple1) # tuple1变为('a', 'b', ['x', 'y', 'z'])

tuple的创建

1
2
3
tuple2 = (1, "good", 2, 3, "good", True)  # 创建元组,里面的元素类型可以不同
tuple3 = ("a", "b", *tuple2, 4, 5) # 元组引用另一个数组中的所有元素
print("tuple3: ", tuple3)

tuple中元素的增删改查

1
2
3
4
5
6
7
8
9
10
11
element = tuple2[4]  # 根据索引获取元组中的元素
element = tuple2[-2] # 使用索引获取元组中的元素
index = tuple2.index("good") # 获取第一个匹配给定值的index值
del tuple2 # 删除元组
# tuple2[4] = "well" # 修改元组的元素,报错

tuple4 = ("a", "b", 4, 5, [6, 7, 8])
print("tuple4: ", tuple4)
# tuple4[-1] = [10, 20, 30] #报错
tuple4[-1][0] = 100 # 可以通过修改元组中的list,从而改变元组
print("tuple4: ", tuple4) # tuple4: ('a', 'b', 4, 5, [100, 7, 8])

tuple的遍历

注:tuple的遍历同list