04 python开发之数据类型
4 数据类型
4.1 概述
4.1.1 基本概念
-
不同种类的数据存取机制不一样,用途也不一样
-
数据是事物的状态,事物的状态是分为多种多样的,对应着就应该用不同类型的数据去记录。
-
具体什么场景用什么类型
-
有以下6种类型:
整型 int
浮点型 float
字符串 str
列表类型 list
字典类型 dict
布尔类型 bool
4.1.2 整型int
-
作用:记录年龄、等级、号码、个数...
-
定义:用整数表示变量的值
age = 18 # age=int(18)
number = 23 # number=int(23)
print(age,type(age)) # type查看数据类型
4.1.3 浮点型float
-
作用:记录身高、体重、薪资...
-
定义:用小数表示变量的值
salary = 3.3 # salary=float(3.3)
height = 1.7 # height=float(1.7)
4.1.4 字符串str
-
作用:记录描述性质的内容,如名字、国籍、爱好、一段话...
-
定义:用''或""或""" """或''' '''中间包含一系列字符
单行:''、""
多行:''''''、""""""
msg1 = 'hello yue'
msg2 = "hello yyy"
msg3 = """
1111
2222
3333
"""
msg4 = '''
44444
55555
66666
'''
# 外层双引号,内层就要用单引号
print("my name is 'ccc'")
4.1.5 列表类型list
-
作用:按照顺序存放多个值,并且可以按照顺序取出指定的值
-
定义:在[]内用逗号分隔开多个任意类型的值,列表可以套多个列表
正向取值
# 0 1 2 3
# 0 1 2
# 0 1
L = [111,3.4,'abc',['xxx','www',[333,4444]]]
print(L[0]) # 输出:111(索引从0开始)
反向取值
print(L[-1]) # 输出: ['xxx', 'wwww', [333, 444]]
print(L[-3]) # 3.4
print(l[-1][2][0]) # 333
4.1.6 字典类型dict
-
作用:按照属性存放多个值,key:value组合
-
定义:在{}内用逗号分隔开多个key:value,key通常是str类型,value可以是任意类型
info = {
"name": "ccc",
"age": 18,
"gender": "male",
"annual_salary": 18,
"level": 10
}
# 输入查找条件,按照键值对取值
print(info['age']) # 输出:18
# 字典嵌套
# 例
d = {"k1": 111, "k2": 222, "k3": [444, 555], "k4": {"a": 1, "b": 2}}
print(d["k3"][0]) # 输出:444
print(d["k4"]["a"]) # 输出:1
4.1.7 布尔类型bool
-
作用:True和False,通常用作条件,用于判断
-
定义:tag = True或tag = False
# 显式的布尔值
tag = True
tag = False
# 隐式的布尔值
# 所有数据类型的值都可以作为隐式布尔值使用
# 其中0、空、None三者的布尔值为False,其余均为True
# print(bool(1)) # True
# print(bool(0)) # False
# print(bool([])) # False
# print(bool("")) # False
# print(bool("")) # False
# print(bool({})) # False
# print(bool(None)) # False
x = True
y = False
print(type(x)) # bool
x = None
print(x is None) # True
4.2 可变与不可变类型
4.2.1 可变类型(不可hash类型)
-
值改变的情况下,内存地址/id不变
-
证明改变的就是原值,即可变类型
l = [111, 222]
print(id(l)) # 2725287619456
l[0] = 3333
print(id(l)) # 2725287619456
4.2.2 不可变类型(可hash类型)
-
值改变的情况下,内存地址也变
-
证明产生了新的值,即原值不可变
x = 10
print(id(x)) # 140708016953280
x = 12
print(id(x)) # 140708016953344
4.3 数字类型常用操作及内置方法
4.3.1 整型及浮点型
- 整型int
1、用途:年龄、等级、号码...
2、定义方式:
age = 18 # age = int(18)
3、数据类型转换
x = int(" 103 ") # 把纯数字组成的字符串转换成int类型(前后的空格可消,中间有会报错)
print(x, type(x)) # 103 <class 'int'>
- 浮点型float
1、用途:身高、体重、薪资...
2、定义方式:
salary = 3.3 # salary = float(3.3)
3、数据类型转换
x = float(" 3.3 ")
print(x, type(x)) # 3.3 <class 'float'>
4.3.2 其他数字类型(了解)
- 长整型long
在python2中(python3中没有长整形的概念):
>>> num=2L
>>> type(num)
<type 'long'>
- 复数
>>>x=1-2j
>>>x.real
1.0
>>>x.imag
-2.0
4.3.3 常用操作及内置方法
-
整型int
+ - * / % > <= // **
-
浮点型float
+ - * / % > <= // **
4.3.4 总结
- 整型int
只能存一个值
不可变
- 浮点型float
只能存一个值
不可变
4.3.5 补充:进制
-
十进制 : 0 1 2 3 4 5 6 7 8 9
二进制 : 0 1
八进制 : 0 1 2 3 4 5 6 7
十六进制:0 1 2 3 4 5 6 7 8 9 a b c d e f
-
命令操作
print(bin(11)) # 十进制转二进制
print(oct(11)) # 十进制转八进制
print(hex(11)) # 十进制转十六进制print(int("11", 2)) # 二进制转十进制
print(int("11", 8)) # 八进制转十进制
print(int("11", 16)) # 十六进制转十进制 -
自由计算
十进制<---二进制 1011 1*2^3 + 0*2^2 + 1*2^1 + 1*2^0 8 + 0 + 2 + 1 = 11 十进制<---八进制 1011 1*8^3 + 0*8^2 + 1*8^1 + 1*8^0 512 + 0 + 8 + 1 = 521 十进制<---十六进制 1011 1*16^3 + 0*16^2 + 1*16^1 + 1*16^0 4096 + 0 + 16 + 1 = 4113 十进制--->二进制(除二取余) 11 11/2=5-1 5/2=2-1 2/2=1-0 最终得到1011 十进制--->八进制(除八取余) 十进制--->十六进制(除十六取余)
4.4 字符串类型常用操作及内置方法
4.4.1 概述
-
用途:记录一些描述性质的内容,如国籍、名字、一段话...
-
定义方式:
msg = "abc" # msg = str("abc")
-
数据类型转换:
res = str(111) # 可以把所有类型都转换成str类型
print(res, type(res)) # 111 <class 'str'>
4.4.2 常用操作及内置方法(*****)
-
按索引取值(正向取+反向取):只能取
-
切片(顾头不顾尾,步长)
-
长度len
-
成员运算in和not in
-
移除空白strip
-
切分split
-
循环
# 按索引取值(正向取+反向取):只能取
msg = "hello world"
print(msg[0])
msg[0] = "H" # 报错,不能改
# 切片(顾头不顾尾,步长)
msg = "hello world"
print(msg[3:5]) # lo
print(msg[3:8:2]) # l o
print(msg[-1:2:-2]) # drwo
print(msg[::2]) #hlowrd
print(msg[-1::-1]) # dlrow olleh
# 长度len:统计的是字符个数
msg = "h e你"
print(len(msg)) # 4(一个空格、一格中文字符都是一个字符)
# 成员运算in和not in
msg = "hello world"
print("he" in msg) # True
print("d" in msg) # True
print("hd" in msg) # False
print("hd" not in msg) # True
# 移除空白strip(只会移除两边,不会移除内部)
name = " cc c "
print(name.strip()) # cc c
print(name) # cc c
name = "**********ccc***********"
print(name.strip("*")) # ccc
x = "*-/+()=abc*(-)/*"
print(x.strip("-+*/(=)")) # abc
name = input("username>>>:").strip()
pwd = input("password>>>:").strip()
if name == "ccc" and pwd == "123":
print("ok")
else:
print("error")
# 切分split
info = "root: 123: 2: 0"
res = info.split(":", 1)
print(res[0])
print(res)
# 循环
msg = "hello"
for i in msg:
print(i)
4.4.3 常用操作及内置方法(****)
-
strip移除空白,lstrip移除左边空白,rstrip移除右边空白
-
lower全小写输出,upper全大写输出
-
startswith判断是否以什么开头,endswith判断是否以什么结尾
-
format
-
split切分,rsplit
-
jion用一个字符把列表连在一起
-
replace替代
-
isdigit判断是否为整型
1、strip移除两边空白、lstrip移除左边空白、rstrip移除右边空白
name = "*egon**"
print(name.strip('*'))
print(name.lstrip('*'))
print(name.rstrip('*'))
2、lower全小写输出、upper全大写输出
name = '*eGon**'
print(name.lower())
print(name.upper())
3、判断是否以什么开头startswith或结尾endswith
name = 'alex_SB'
print(name.endswith('SB'))
print(name.startswith('alex'))
4、format三种玩法
字符串格式化
方式1
res = "my name is %s my age is %s" % ("egon", 18)
print(res)
方式2
res = '{} {} {}'.format('egon', 18, 'male')
res = '{1} {0} {1}'.format('egon', 18, 'male')
res = '{name} {age} {sex}'.format(sex='male', name='egon', age=18)
print(res)
======================format
套用字典.format(**字典))
kwargs = {'name': "ccc", 'age': 18}
print('我的名字是{name},我的年龄是{age}'.format(**kwargs))
套用列表.format(*列表))
l = [111, 222]
print('我的名字是{},我的年龄是{}'.format(*l))
对齐
res = "my name is {} my age is {}".format("ccc", 18)
res = "my name is {0:*<10} my age is {1}".format("ccc", 18)
res = "my name is {0:@>10} my age is {1}".format("ccc", 18)
res = "my name is {0:-^10} my age is {1:=^10}".format("ccc", 18)
print(res)
进制与精度b二进制、o十进制、x十六进制、,科学输出、.3f保留三位小数四舍五入
res = "my name is {0} my age is {1:b}".format("ccc", 18)
res = "my name is {0} my age is {1:o}".format("ccc", 18)
res = "my name is {0} my age is {1:x}".format("ccc", 18)
res = "my name is {0} my age is {1:,}".format("ccc", 180000000000)
res = "my name is {0} my age is {1:.3f}".format("ccc", 6.666666)
print(res)
======================f""
name = "egon"
age = 18
res = f"my name is {name} my age is {age}"
print(res)
5、切分.split('分隔符')
name = 'root:x:0:0::/root:/bin/bash'
print(name.split(':'))
print(name.split('/'))
name = 'C:/a/b/c/d.txt'
print(name.split('/'))
name = 'a|b|c'
print(name.rsplit('|', 1))
6、join用一个字符把列表连在一起(列表内都是字符串)
tag = '/'
print(tag.join(['egon', 'say', 'hello', 'world']))
l = ["1111", "2222", "3333"]
res = ':'.join(l)
print(res)
7、replace替换
name = 'alex say : i have one tesla, my name is alex'
print(name.replace('alex', 'SB'))
8、isdigit判断是否是整型
print("abc".isdigit())
print(" 123 ".isdigit())
print("123".isdigit())
age = input("your age:").strip()
if age.isdigit():
age = int(age)
if age > 18:
print("too old")
elif age < 18:
print("too young")
else:
print("you got it")
else:
print("You have to enter a number")
了解部分
name = 'egon say hello'
print(name.find('1', 1, 3))
print(name.find('on'))
print(name.index('1', 1, 3))
print(name.count('e', 6,))
name = 'egon'
print(name.center(10, '-'))
print(name.ljust(10, '+'))
print(name.rjust(10, '@'))
print(name.zfill(10))
name = 'egon hello'
print(name)
print(name.expandtabs(2))
name = "egOn"
print(name.capitalize()) # Egon
print(name.swapcase()) # EGoN
msg = 'egon say hi'
print(msg.title()) # Egon Say Hi
is数字系列
num1 = b'4'
num2 = u'4'
num3 = '四'
num4 = 'Ⅳ'
.isdigit判断bytes、unicode
print(num1.isdigit()) # True
print(num2.isdigit()) # True
print(num3.isdigit()) # False
print(num4.isdigit()) # False
.isdecimal判断unicode
print(num2.isdecimal()) # True
print(num3.isdecimal()) # False
print(num4.isdecimal()) # False
.isnumeric判断unicode、中文、罗马
print(num2.isnumeric()) # True
print(num3.isnumeric()) # True
print(num4.isnumeric()) # True
is其他
print('===>')
name = 'egon123'
print(name.isalnum()) # 字符串由字母或数字组成
print(name.isalpha()) # 字符串只由字母组成
print(name.isidentifier())
print(name.islower())
print(name.isupper())
print(name.isspace())
print(name.istitle())
4.4.4 总结
-
只能存一个值
-
是有序的
-
不可变
4.5 列表类型常用操作及内置方法
4.5.1 概述
-
用途:按照位置记录多个值---->索引对应值
-
定义方式:在[]内用逗号分隔开多个任意类型的值
l = [111, 11.11, "aaa", [222, 333]] # l = list(...)
-
数据类型转换:
print(list("hello")) # ['h', 'e', 'l', 'l', 'o']
print(list({'k1': 111, 'k2': 222})) # ['k1', 'k2']
print(list(range(5))) # [0, 1, 2, 3, 4]
4.5.2 常用操作及内置方法(*****)
-
按照索引取值(正向取+反向取):可改可取
-
.append()追加
-
.insert()插入
-
.remove, .pop, del删除
-
切片
-
len长度
-
成员运算in和not in
-
循环
# 按索引存取值(正向取+反向取):可改可取
l = ["aaa", "bbb", 111]
print(l[0]) # aaa
print(l[-1]) # 111
print(id(l)) # 2724827099008
l[0] = "xxx"
print(l) # ['xxx', 'bbb', 111]
print(id(l)) # 2724827099008
l[3] = "ccc" # 报错list assignment index out of range
# 追加
l = ["aaa", "bbb", 111]
l.append("ddd") # 不会有任何返回值
print(l) # ['aaa', 'bbb', 111, 'ddd']
l.append("eee") # 在最后面追加
print(l) # ['aaa', 'bbb', 111, 'ddd', 'eee']
# 插入
l = ["aaa", "bbb", 111]
res = l.insert(1, "qqq") # 在位置前加
print(l) # ['aaa', 'qqq', 'bbb', 111]
print(res) # None
# 删除
l = ["aaa", "bbb", 111]
# Ⅰ 万能删除
del l[0]
print(l) # ['bbb', 111]
# Ⅱ l.remove指定元素删除
res = l.remove(111)
print(l) # ['aaa', 'bbb']
print(res) # 没有返回值None
# Ⅲ l.pop指定索引删除,会有返回值,返回的是删除的元素
res = l.pop(0)
print(l) # ['bbb', 111]
print(res) # aaa
# 切片(顾头不顾尾,步长)
l = [111, 222, 333, 444, 555, 666, 777]
print(l[0:5]) # 0 1 2 3 4
print(l[0:5:2]) # 0 2 4
print(l[:]) # 拷贝到新列表
print(l[::-1]) # 反向
# 长度
l = [111, 222, 333, 444, 555, 666, 777]
print(len(l)) # 7
成员运算in和not in
l = [111, 222, 333, 444, 555, 666, 777]
print(111 in l) # True
print(000 not in l) # True
# 循环
l = [111, 222, 333, 444, 555, 666, 777]
for i in l:
print(i)
4.5.3 常用操作及内置方法(****)
-
.count()计数
-
.extend()追加
-
.reverse()反向
-
.index()区间计数,没有就报错
-
.clear()清空
-
.sort()排序
-
.copy()拷贝
# .count计数
l = [111, 222, 111, 444]
print(l.count(111)) # 2
# .extend追加
l = [111, 222, 111, 444]
l.extend('hello')
l.extend("xxx", "yyy") # 报错
print(l) # [111, 222, 111, 444, 'h', 'e', 'l', 'l', 'o']
# .reverse反向
l = [111, 222, 111, 444]
res = l.reverse() # 没有输出
print(l) # [444, 111, 222, 111]
print(res) # None
# .index
l = [111, 222, 111, 444]
print(l.index(111, 1, 3)) # 2 区间计数
print(l.index("xxx", 1, 5)) # 没有就报错
# .clear
l = [111, 222, 111, 444]
l.clear()
print(l) # [] 清空
# .sort排序
# l = [3, -1, 4, 9.9, 7]
# l.sort() # 从小到大
# l.sort(reverse=True) # 从大到小
# print(l) # [9.9, 7, 4, 3, -1]
# l = [3, -1, 4, 9, 7, "x"] # 不能有字符串,只能是数字型
# .copy
res1 = l.copy() # 浅拷贝
res2 = l[:] # 浅拷贝
print(res1)
print(res2)
======================浅拷贝
l1 = ["china", 333, [300, 100]]
l2 = l1.copy()
print(l1) # ['china', 333, [300, 100]]
print(l2) # ['china', 333, [300, 100]]
l1[2][0] -= 100
print(l1) # ['china', 333, [200, 100]]
print(l2) # ['china', 333, [200, 100]]
print(id(l1[0]), id(l1[1]), id(l1[2])) # 2806369619312 2806368532944 2806371052288
print(id(l2[0]), id(l2[1]), id(l2[2])) # 2806369619312 2806368532944 2806371052288
l1[0] = 'xxx'
print(l1) # ['xxx', 333, [300, 100]]
print(l2) # ['china', 333, [300, 100]]
print(id(l1[0]), id(l1[1]), id(l1[2])) # 1971974639152 1971973552592 1971976072064
print(id(l2[0]), id(l2[1]), id(l2[2])) # 1971974639152 1971973552592 1971976072064
l1[2][0] = 400
print(l1) # ['china', 333, [400, 100]]
print(l2) # ['china', 333, [400, 100]]
浅拷贝指向第一层,不管是不是列表都只复制一层
第一层数据如果是不可变的,l2就不会变id相应会不同,可变就一起变
======================深拷贝
from copy import deepcopy
l1 = ["china", 333, [300, 100]]
l2 = deepcopy(l1)
print(id(l1[0]), id(l1[1]), id(l1[2])) # 2067178917360 2067177830864 2067181408384
print(id(l2[0]), id(l2[1]), id(l2[2])) # 2067178917360 2067177830864 2067181408960
l1[0] = "xxx"
l1[1] = "yyy"
l1[2][0] = 400
print(l1) # ['xxx', 'yyy', [400, 100]]
print(l2) # ['china', 333, [300, 100]]
深拷贝遇到列表等可变类型时,id就会不一样
深拷贝不会随不可变数据改变而改变
深拷贝是重新分配一块内存,将原数据以递归方式拷贝到新对象中
新对象和原对象没有任何关联
4.5.4 总结
-
可以存多个值
-
有序
-
可变
4.5.5 补充:队列与堆栈
- 队列:FIFO先进先出
l = []
入队列
l.append("first")
l.append("second")
l.append("third")
print(l) # ['first', 'second', 'third']
出队列
print(l.pop(0)) # first
print(l.pop(0)) # second
print(l.pop(0)) # third
- 堆栈:LIFO后进先出
l = []
入栈
l.append("first")
l.append("second")
l.append("third")
print(l) # ['first', 'second', 'third']
出栈
print(l.pop()) # third
print(l.pop()) # second
print(l.pop()) # first
4.6 元组类型常用操作及内置方法
4.6.1 概述
-
用途:按照位置存放多个值,索引对应值
-
定义方式:在()内用逗号分隔开多个任意类型的值
l = (11, 11.11, "aaa", [222, 333]) # l = tuple(...)
print(l[-1][0]) # 222
l[0] = 111 # 报错
-
数据类型转换:
print(tuple('hello')) # ('h', 'e', 'l', 'l', 'o')
t = (111, )
print(type(l)) # <class 'tuple'>
4.6.2 常用操作及内置方法(*****)
-
按索引取值(正向取+反向取):只能取
-
切片(顾头不顾尾,步长)
-
长度
-
成员运算in和not in
-
循环
tuple = (1, "hahah", 12.21, 25, 33)
# 按索引取值(只能取)
print(tuple[0]) # 1
print(tuple[-1]) # 33
tuple[-1] = 55 # 报错
# 切片
print(tuple[0:5:2]) # (1, 12.21, 33)
# 长度
print(len(tuple)) # 5
# 成员运算
print("hahah" in tuple) # True
print(45 not in tuple) # True
# 循环
for line in tuple:
print(line)
# 1
# hahah
# 12.21
# 25
# 33
4.6.3 常用操作及内置方法(****)
t = (11, 222, 333, 222)
print(t.index(333)) # 在元组内就显示在第几个
print(t.index(223332232)) # 不在元组内直接报错
print(t.count(333)) # 计数
4.6.4 总结
- 可以存多个值
- 有序
- 不可变
4.6.5 元组特殊情况
t = (11, 22, ["xx", "yy"])
print(id(t[0]), id(t[1]), id(t[2])) # 140707921795040 140707921795392 1700891389888
# t[0] = 11111 # 报错
# t[2] = 11111 # 报错
t[2][0] = "xxx"
print(t) # (11, 22, ['xxx', 'yy'])
print(id(t[0]), id(t[1]), id(t[2])) # 140707921795040 140707921795392 1700891389888
# 元组内列表数据可变,但id不变
4.7 字典类型常用操作及内置方法
4.7.1 概述
-
用途:存多个值,key:value存取,存取速度快
-
定义方式:在{}内用逗号分隔开多个key:value,key必须是不可变类型,通常是字符串类型,value可以是任意类型的值
info = {'name': 'egon', 'age': 18, 'gender': 'male'} # info = dict({...})
key不能重复,只会显示最后赋给它的值
-
数据类型转换:
info = dict(name = 'egon', age = 18, gender = 'male')
print(info) # {'name': 'egon', 'age': 18, 'gender': 'male'}
info = dict([['name', 'egon'], ('gender', 18)])
print(info) # {'name': 'egon', 'gender': 18}
res = {}.fromkeys(('name', 'age', 'gender'), None)
print(res) # {'name': None, 'age': None, 'gender': None}
l = {} # 花括号内是空字典
print(l, type(l)) # {} <class 'dict'>
4.7.2 常用操作及内置方法(*****)
-
按key取值:可存可取
-
长度len
-
成员运算in和not in
-
删除
-
键keys(),值values(),键值对items()
-
循环
1、按key存取值:可存可取
d = {"k1": 111, "k2": 222, "k3": 333}
d["k1"] = 666
print(d) # {'k1': 666, 'k2': 222, 'k3': 333}
d["k4"] = 999
print(d) # {'k1': 111, 'k2': 222, 'k3': 333, 'k4': 999}
2、长度len
d = {"k1": 111, "k2": 222, "k3": 333}
print(len(d)) # 3
3、成员运算in和not in
字典依据key运算
d = {"k1": 111, "k2": 222, "k3": 333}
print('k1' in d) #True
print(111 in d) # False
4、删除
d = {"k1": 111, "k2": 222, "k3": 333}
方式一
del d['k1']
print(d) # {'k2': 222, 'k3': 333}
方式二
res = d.pop('k1')
print(res) # 111 有返回值(随机删)
print(d) # {'k2': 222, 'k3': 333}
5、键keys(),值values(),键值对items()
d = {"k1": 111, "k2": 222, "k3": 333}
在python2中
>>> d = {"k1": 111, "k2": 222, "k3": 333}
>>> d.keys(),type(d.keys())
(['k3', 'k2', 'k1'], <type 'list'>)
>>> d.values(),type(d.values())
([333, 222, 111], <type 'list'>)
>>> d.items(), type(d.items())
([('k3', 333), ('k2', 222), ('k1', 111)], <type 'list'>)
在python3中
print(d.keys(), type(d.keys())) # dict_keys(['k1', 'k2', 'k3']) <class 'dict_keys'>
print(d.values(), type(d.values())) # dict_values([111, 222, 333]) <class 'dict_values'>
print(d.items(), type(d.items())) # ('k2', 222), ('k3', 333)]) <class 'dict_items'>
6、循环
只取key
for i in d.keys():
print(i)
只取value
for i in d.values():
print(i)
value与key对应
方法一
for i in d:
print(i, d[i])
方法二
for x, y in d.items():
print(x, y)
4.7.3 常用操作及内置方法(****)
d = {"k1": 111, "k2": 222, "k3": 333}
dic = d.copy()
print(dic) # {'k1': 111, 'k2': 222, 'k3': 333}
d.update({'k3': 4646, 'k4': 6666})
print(d) # {'k1': 111, 'k2': 222, 'k3': 4646, 'k4': 6666}
res = d.popitem() # 删除最后一个值,LIFO后进先出
print(res) # ('k3', 333)
print(d) # {'k1': 111, 'k2': 222}
d = {"k2": 222, "k3": 333}
if 'k1' not in d:
d['k1'] = 66666666666
res = d.setdefault('k1', 6666666666) # 两者都可以达成
print(res) # 66666666666 k1不存在的情况下添加
print(d) # {'k2': 222, 'k3': 333, 'k1': 66666666666}
4.7.4 总结
-
可以存多个值
-
无序
-
可变
d = {"k1": 1111}
print(id(d)) # 1844777596544
d['k1'] = 2222
print(id(d)) # 1844777596544
4.7.5 练习
=======================练习1
# 有如下值集合 [11,22,33,44,55,66,77,88,99,90]
# 将所有大于 66 的值保存至字典的第一个key中,将小于 66 的值保存至第二个key的值中
# 即: {'k1': 大于66的所有值, 'k2': 小于66的所有值}
nums = [11, 22, 33, 44, 55, 66, 77, 88, 99]
d = {'k1': [], 'k2': []}
for num in nums:
if num > 66:
d['k1'].append(num)
else:
d['k2'].append(num)
print(d) # {'k1': [77, 88, 99], 'k2': [11, 22, 33, 44, 55, 66]}
=======================练习2
统计s='hello alex alex say hello sb sb'中每个单词的个数
结果如:{'hello': 2, 'alex': 2, 'say': 1, 'sb': 2}
s = 'hello alex alex say hello sb sb'
words = s.split()
d = {}
for x in words:
if x not in d:
d[x] = 1
else:
d[x] += 1
print(d) # {'hello': 2, 'alex': 2, 'say': 1, 'sb': 2}
d.get()
4.8 集合类型常用操作及内置方法
4.8.1 概述
-
作用:去重,关系运算
-
回顾:可变类型是不可hash类型,不可变类型是可hash类型
-
定义方式:在{}内用逗号分隔开多个不可变类型的值
Ⅰ 每个元素必须是不可变类型(可hash,可作为字典的key)
Ⅱ 集合内元素唯一
Ⅲ 集合内元素无序
- 集合的目的不是将不同的值存放到一起
- 不同的集合间来做关系运算,无需纠结集合中单个值
s = {111, 111, 3.3, "aaa", 3.3, (111, 222)} # s = set(...)
print(s) # {(111, 222), 3.3, 'aaa', 111}
-
数据类型转换:
res = set('hello')
print(res, type(res)) # {'h', 'e', 'l', 'o'} <class 'set'>
4.8.2 常用操作及内置方法(*****)
-
长度len
-
成员运算in和not in
-
关系运算
1、长度len
s = {111, 222, 333}
print(len(s)) # 3
2、成员运算in和not in
s = {111, 222, 333}
print(111 in s) # True
print(11 not in s) # True
=====================关系运算
pythons = {'alex', 'egon', 'yuanhao', 'wupeiqi', 'gangdan', 'biubiu'}
linuxs = {'wupeiqi', 'oldboy', 'gangdan'}
3、|合集
print(pythons | linuxs) # 方法一
print(pythons.union(linuxs)) # 方法二
# {'yuanhao', 'egon', 'wupeiqi', 'gangdan', 'biubiu', 'oldboy', 'alex'}
4、&交集:共同部分
print(pythons & linuxs) # 方法一
print(pythons.intersection(linuxs)) # 方法二
# {'gangdan', 'wupeiqi'}
# 将交集更新给pythons
pythons = pythons & linuxs # 方法一
pythons.intersection_update(linuxs) # 方法二
print(pythons)
# {'wupeiqi', 'gangdan'}
5、-差集
# pythons有而linuxs没有
print(pythons - linuxs) # 方法一
print(pythons.difference(linuxs)) # 方法二
# {'alex', 'biubiu', 'yuanhao', 'egon'}
# linuxs有而pythons没有
print(linuxs - pythons) # 方法一
print(linuxs.difference(pythons)) # 方法二
# {'oldboy'}
6、^对称差集:取出pythons有或linuxs有的
res = pythons ^ linuxs # 方法一
print(res)
res = pythons.symmetric_difference(linuxs) # 方法二
print(res)
res = (pythons - linuxs) | (linuxs - pythons) # 繁琐
print(res)
res = (pythons | linuxs) - (pythons & linuxs) # 繁琐
print(res)
# {'alex', 'yuanhao', 'biubiu', 'egon', 'oldboy'}
7、==
s1 = {1, 2, 3}
s2 = {3, 2, 1}
print(s1 == s2) # True
8、父集:>,>=
9、子集:<,<=
s1 = {1, 2, 3, 4, 5}
s2 = {3, 2, 1}
print(s1 >= s2) # True
print(s1 <= s2) # False
4.8.3 常用操作及内置方法(****)
-
.update 更新
-
.pop 随机删
-
.remove 具体删掉某一值
-
.discard 删掉不存在的值会报错,remove不会
-
.add 添加值,位置随机,因为集合无序
-
.isdisjoint 判断两个集合是否包含相同的元素
.update 更新
s = {"aaa", 22, 3.3, "bbb"}
s.update({22, 3, 4, 5})
print(s) # {3.3, 3, 4, 5, 'aaa', 'bbb', 22}
.pop 随机删
s = {"aaa", 22, 3.3, "bbb"}
res = s.pop()
print(res) # 3.3 有输出结果,随机删
print(s) # {'bbb', 'aaa', 22}
.remove 具体删掉某一个值
s = {"aaa", 22, 3.3, "bbb"}
res = s.remove("bbb")
print(res) # None 没有输出结果
print(s) # {'aaa', 3.3, 22}
.discard 删不存在的值会报错,remove不会
s = {"aaa", 22, 3.3, "bbb"}
s.discard("ccc") # 没有该值会直接报错
print(s)
s.remove("ccc") # 没有该值不会报错,返回原值
print(s) # {'aaa', 3.3, 22, 'bbb'}
.add 添加值,位置随机,因为集合无序
s = {"aaa", 22, 3.3, "bbb"}
s.add("ccc")
print(s) # {3.3, 'aaa', 'ccc', 22, 'bbb'}
isdisjoint 判断两个集合是否包含相同的元素
s1 = {1, 2, 3}
s2 = {4, 5, 6, 3}
print(s1.isdisjoint(s2)) # False
4.8.4 总结
-
可以存多个值
-
无序
-
可变
s = {1, 2, 3}
print(id(s)) # 2189058917984
s.add(4)
print(id(S)) # 2189058917984
4.8.5 练习
# ==========================练习1
# 有如下列表,列表元素为不可hash类型,去重,得到新列表,
# 且新列表一定要保持列表原来的顺序
# l=[
# {'name':'egon','age':18,'sex':'male'},
# {'name':'alex','age':73,'sex':'male'},
# {'name':'egon','age':20,'sex':'female'},
# {'name':'egon','age':18,'sex':'male'},
# {'name':'egon','age':18,'sex':'male'},
# ]
l = [
{'name': 'egon', 'age': 18, 'sex': 'male'},
{'name': 'alex', 'age': 73, 'sex': 'male'},
{'name': 'tony', 'age': 20, 'sex': 'female'},
{'name': 'egon', 'age': 18, 'sex': 'male'},
{'name': 'egon', 'age': 18, 'sex': 'male'},
]
res = []
for item in l:
if item not in res:
res.append(item)
print(res)
# [{'name': 'egon', 'age': 18, 'sex': 'male'},
# {'name': 'alex', 'age': 73, 'sex': 'male'},
# {'name': 'tony', 'age': 20, 'sex': 'female'}] # 三行同一行
4.9 数据类型总结
4.9.1 按照存储空间的占用分(低到高)
数字
字符串
集合:无序,无需存索引相关信息
元组:有序,需要存索引相关信息,不可变
列表:有序,需要存索引相关信息,可变,需要处理数据的增删改
字典:无序,需要存key和value映射的相关信息,可变,需要处理数据的增删改
4.9.2 按存储个数区分
Ⅰ 标量/原子类型 数字、字符串
Ⅱ 容器类型 列表、元组、字典
4.9.3 按可变不可变区分
Ⅰ 可变 列表、字典
Ⅱ 不可变 数字、字符串、元组
4.9.4 按访问顺序区分
Ⅰ 直接访问 数字
Ⅱ 顺序访问(序列类型) 字符串、列表、元组
Ⅲ key值访问(映射类型) 字典