T5-字典、集合和序列

  • 5 字典、集合和序列
  • 5.1 字典
  • 5.1.1 字典的定义
  • 5.1.2 创建和访问字典
  • 5.1.3 字典的内置方法
  • 5.1.4 【练习题】



【可变类型与不可变类型】

  • 序列是以连续的整数为索引,与此不同的是,字典是以"关键字"为索引,关键字可以是任意不同类型,通常用字符串或者数值。
  • 字典是Python中唯一的一个映射类型,字符串、元组、序列是属于序列类型。
  • 如何快速判断一个数据类型x 是不是可变类型呢?两种方法;
  • 麻烦方法:用id(x)函数,对x进行某种操作,比较操作前后的id,如果不一样,则x不可变,如果一样,则x可变。
  • 便捷方法:用hash(x),只要不报错,证明x可被哈希,即不可变,反过来不可被哈希,即可变。
    【例子】
i=1
print(id(i))  # 140732167000896
i=i+2
print(id(i)) # 140732167000960

l=[1,2]
print(id(l)) # 4300825160
l.append('python') # 4300825160
  • 整数i在加1之后的id和之前不一样,因此加完之后的这个i(虽然名字没变),但不是加之前的那个i了,因此整数是不可变类型。
  • 列表l在附加‘Python’之后的id和之前一样,因此列表是可变类型。
    【例子】
print(hash('Nmae'))        # 9215951442099718823
print(hash(1,2,'Python'))  # 823362308207799471

print(hash([1,2,'python'])) # TypeError: unhashable type: 'list'

print(hash({1,2,3}))           # TypeError:unhashale type:'set'
  • 数值、字符和元组 都能被哈希,因此他们是不可变类型。
  • 列表、集合、字典不能被哈希,因此它是可变类型。

5 字典、集合和序列

5.1 字典

字典是可变类型。

5.1.1 字典的定义

字典是 无序的 键:值(key:value)对集合,键必须是互相不相同的(在同一个字典内)。

  • dict 内部存放的顺序和key放入的顺序是没哟关系的。
  • dict 查找和插入的速度极快不会随着key的值增加而增加,但是需要占用大量的内存。
    字典定义的语法为:{元素1,元素2,…,元素n}
  • 其中每一个元素是一个[键值对]–键:值(key:value)
  • 关键点是【大括号{}】、【逗号,】和【冒号:】
  • 大括号–把所有的元素绑在一起
  • 逗号–将每个键值对分开
  • 冒号–将键和值分开

5.1.2 创建和访问字典

  • 通过都是字符串来创建字典;
    【例子】
brand =['李宁','耐克','阿迪达斯']
slogan=['一切皆有可能','Just do it','Impossible is nothing']
print('耐克的口号是:',slogan[brand.index('耐克')])  ## brand.index('耐克')的结果为1; 
# 耐克的口号是:Just do it

dic={'李宁':'一切皆有可能','耐克':'Just do it','阿迪达斯':'Impossible is nothing'}
print('耐克的口号是:',dic['耐克'])
# 耐克的口号是:Just do it
  • 通过字符串或者数值作为key来创建字典
    【例子】
dic1={1:'one',2:'two',3:'three'}
print(dic1)      # {1:'one',2:'two',3:''three}
print(dic1[1])  # one
print([dic[4]])  # KeyError: 4

dic2={'rice':35,'wheat':101,'corn':67}
print(dic2)      #{'wheat':101,'corn':67,'rice':35}
print(dic2['rice'])      # 35

注意:如果我们取的键在字典中不存在,会直接报错KeyError

  • 通过元组作为key来创建字典
    【例子】
dic={(1,2,3):'Tom','Age':12,3:[3,5,7]}
print(dic)             # {(1,2,3):'Tom','Age':12,3:[3,5,7]}
print(type(dic))     # <class 'dict'>
  • 通过构造函数dict来创建字典
  1. dict()创建一个空的字典
    通过key直接把数据放入字典中,但一个key只能对应一个value,多次对一个key放入value,后面的值会把前面的值冲掉。
dic = dict() # 创建一个空的字典
dic['a']=1
dic['b']=2
dic[''c]=3

print(dic)     # {'a':1,'b':2,'c':3}

dic['d'] = 4
print(dic)    # {'a':11,'b':2,'c':3,'d':4}
  1. dict(mapping)从映射对象的(键,value)初始化新字典
    【例子】
dict1=dict([('apple',4139),('peach',4127),('cherry',4098)])
print(dic1)   #{'cherry':4098,'apple':4139,'peach':4127}

dic2=dict((('apple',4139),('peach',4127),('cherry',4098)))
print(dic2)   #{'peach':4127,'cherry':4098,'apple':4139}
  1. dict(**kwargs)->使用name=value对在关键字参数列表中新建初始化字典。例如:dict(one=1,two=2)
    这种情况下,键只能为字符串类型,并且创建的时候字符串不能加引号,加上就会直接报语法错误。
dic=dict(name='Tom',age=10)
print(dic)                 # {"name":'Tom','age':10}
print(type(dic))         # <class 'dict'>

5.1.3 字典的内置方法

  • dict.fromkeys[seq,[value])用于创建新字典,以序列seq中元组做字典的键(Key),value为字典所有键对应的初始值。
    【例子】
seq=('name','age','sex')
dic1=dict.fromkeys(seq)
print(dic1)             # {'name':none,'age':None,'sex':None}

dic2=dict.fromkeys(seq,10) 
print(dic2)              # ('name':10,'age':10,'sex':10)

dic3=dict.fromkeys(seq,('小马','8','男'))
print(dic3)             # {'name': ('小马', '8', '男'), 'age': ('小马', '8', '男'), 'sex': ('小马', '8', '男')}
  • dict.keys()返回一个可迭代对象,可以使用list()来转换为列表,列表为字典中的所有键。
    【例子】
dic={'Name':'lsgogroup','Age':7}
print(dic.keys())  # dict_keys(['Name','Age'])
lst=list(dic.keys())            # 转换为列表
print(lst)                         # ['Name','Age']
  • dict.values()返回一个迭代器,可以使用list()来转换为列表,列表为字典中的所有值。
    【例子】
dic={'Sex':'female','Age':7,'Name':'Zara'}
print(dic.values())
# dict_values(['female',7,'Zara'])

print(list(dic.values()))
# [7,'female','Zara']
  • dict.items()以列表返回可遍历的(键:值)元组数组
    【例子】
dic={'Name':'Lsgogroup','Age';7}
print(dic.items())    
# dict_items([('Name','Lsgoroup'),('Age',7)])

print(tuple(dic.items()))
# (('Name','Lsgogroup'),('Age',7))

print(list(dic.items()))
# [('Name','Lsgogroup'),('Age',7)]
  • dict.get(Key,default=None) 返回指定键的Key(值),如果值不在字典中返回默认值
    【例子】
dic={'Name':'Lsgogroup','Age':27}
print('Age 值为 : %s' %dic.get('Age'))   # Age 的值为 :27
print("Sex 的值为 : %s" %dic.get('Sex','NA'))  # Sex 的值为:NA
print(dic)    # {'Name':'Lsgogroup','Age':27}
  • dict.setdefault(key,default=None)和get()方法类似,如果键值不存在于字典中,将会添加键并将值设为默认值
    【例子】
dic={'Name':'Lsgogroup','Age':7}
print('Age 键的值为 :%s' % dic.setdefault('Age',None))   # Age 键的值为: 7
print('Sex 键的值为:%s ' dic.setdefault('Sex',None))          # Sex 键的值为:None
print(dic)          # {'Age':7,'Name':'Lsgogroup','Sex':None}
  • key in dict,in操作符用于判断键是否存在于字典中,如果键在字典dict里返回true,否则返回false。而not in操作符刚好相反,如果键在字典dict里返回false,否则返回true。
    【例子】
dic={'Name':'Lsgogroup','Age':7}
# in 检测键Age是否存在
if  'Age' in dic:
    print('键 Age存在')
else:
    print('键 Age 不存在')

# 检测键 Sex是否存在
if 'Sex' in dic:
    print('键 Sex存在')
else:
    print('键 Sex不存在')

# not in 检测键 Age是否存在
if 'Age' not in dic:
    print('键 Age不存在')
else:
    print('键 Age存在')
# 键 Age存在
# 键 Sex不存在
# 键 Age 存在
  • dict.pop(key,[default])删除字典给定键key所对应的值,返回值为被删除的值。key关键字必须给出,若key不存在,则返回default值。
  • del dict[key] 删除字典给定键key所对应的值
    【例子】
dic1=[1:'a',2:[1,2]]
print(dic1.pop(1),dic1) 	# a {2:[1,2]}

# 设置默认值,必须添加,否则报错
print(dic1.pop(3,'nokey'),dic1)  # nokey    {2:[1,2]}

del dic1[2]
print(dic1)    # {}
  • dict.popitem()随机返回并删除字典中的一对键和值,如果字典已经为空,却调用了此方法,就爆出KeyError异常。
    【例子】
dic1={1:"a",2:[1,2]}
print(dic1.popitem())  # (1,'a')
print(dic1)                 # {2:[1,2]}
  • dict.clear()用于删除字典内的所有元素
    【例子】
dic = {'Name':'Zara','Age':7}
print('字典长度':%d' % len(dic))  # 字典长度:2
dic.clear()
print('字典删除后长度: %d' %len(dic))  # 字典删除后长度:0
  • dict.copy() 返回一个字典的浅复制
    【例子】
dic1={'Name':'Lsgogroup','Age':7,'Class':'First'}
dic2=dic1.copy()
print(dic2)           # {'Age':7,'Name':'Lsgogroup','Class':'First'} 
# 【例子】直接赋值和copy的区别
dic1={'user':'lsgoroup','num':[1,2,3]}

# 引用的对象
dic2=dic1
# 浅拷贝父对象(一级目录),子对象(二级目录)不拷贝,还是引用
dic3=dic1.copy()

print(id(dic1))  # 148635574728
print(id(dic2))  # 148635574728
print(id(dic3))  # 148635574344

# 修改data数据
dic1['user']='root'
dic['num'].remove(1)

# 输出结果
print(dic1)   # {'user':'root','num':[2,3]}
print(dic2)   # {'user':root,'num:[2,3]'}
print(dic3)   # {'user':'runoob','num':[2,3]}
  • dict.upadte(dic2)把字典参数dict2的key:value对 更新到字典dict里。
    【例子】
dic={'Name':'Lsgogroup','Age':7}
dic2={'Sex':'Female','Age':8}
dic.update(dic2)
print(dic)
# {'Sex':'female','Age':8,'Name':'Lsgogroup'}

5.1.4 【练习题】

  1. 字典基本操作
    字典内容如下:
dic={
'python':95,
'Java':90,
'c':100
}

用程序解答下面题目:

  • 字典的长度是多少? len(dic)
  • 修改’Java’这个key对应的value值为98 dic[‘java’]=98
  • 删除c这个key. del dic[‘c’]
  • 增加一个key-value对,key值为php,value是90 dic[‘php’]=90
  • 获取所有的key值,存储在列表里 lst=list(dic.keys()) # 转换为列表
  • 获取所有的value值,存储在列表里 lst=list(dic.values())
  • 判断javascript是否在字典中 dic[‘javascript’]
  • 获得字典里的所有value值和 sum =0 for i in list(dic.values()): sum=sum+i
  • 获得字典里最大的value lst.max()
  • 获得字典里最小的value lst.min()
  • 字典dic1={‘php’:97},将dic1的数据更新到dic中 dic.update(dic1)
  1. 字典中的value
    有一个字典,保存的是学生个个编程语言的成绩,内容如下:
data = {
        'python': {'上学期': '90', '下学期': '95'},
        'c++': ['95', '96', '97'],
        'java': [{'月考':'90', '期中考试': '94', '期末考试': '98'}]
        }

各门课程的考试成绩存储方式并不相同,有的用字典,有的用列表,但是分数都是字符串类型,请实现函数transfer_score(score_dict),将分数修改成int类型。