元组和字典
Ⅰ 元组
1. 什么是元组(tuple)
元组是容器型数据类型,将()作为容器标志,里面多个元素用逗号隔开:(元素1,元素2,元素3…)
元组不可变 - 空元组无意义,只能查操作
元组是有序 - 支持下标操作
元素:和列表一样没有要求
1-1 空元组
ti = ()
print(type(ti), len(ti)) # <class 'tuple'> 0
1-2 一个元素的元组
t2 = (12)
t3 = (12,)
print(t2, type(t2)) # 12 <class 'int'>
print(t3, type(t3)) # (12,) <class 'tuple'>
1-3 普通元组
t4 = (1,2,3)
print(type(t4), t4) # <class 'tuple'> (1, 2, 3)
1-4 省略括号的元组
在没有歧义的情况下,元组的小括号可以省略(直接将多个数据用逗号隔开表示的也是一个元组)。
t5 = 10, 32, 65
print(type(t5), t5) # <class 'tuple'> (10, 32, 65)
t6 = 10, 20, 30*2
print(type(t6), t6) # <class 'tuple'> (10, 20, 60)
2. 查 - 获取元素
2-1 列表方式元组都支持
# 更多方式请看看列表一章节
nums = (1, 2, 3, 6, 5, 4)
print(nums[0], nums[-1]) # 1 4
2-2 通过变量直接获取元组的元素1
point = (10, 23, 15)
x, y, z = point
print(x, y, z) # 10 23 15
2-3 通过变量直接获取元组的元素2
变量的个数小于元组元素的个数,那么必须在其中一个变量前加*,
取得时候先让没有号的变量按照位置关系获取元素,剩下的全部元素给带号的变量(以列表形式)
info = ('张三', 18, 180, 175, '中国')
name, age, *other = info
print(name, age, other, type(other)) # 张三 18 [180, 175, '中国'] <class 'list'>
name, *other, address = info
print(name, other, address) # 张三 [18, 180, 175] 中国
3.元组是不可变的
元组是不可变的列表 - 列表中不可变相关操作元组都支持
# +、*
# in 和 not in
# 比较运算
# 元组.count() / 元组.index()
# max / min / sum / sorted / len / tuple
print(info.count(18)) # 元组获取18出现次数
print(info.index(175)) # 元组获取175的下标
Ⅱ 字典
1. 字典的作用
字典的作用 - 同时保存多个意义不同的数据(键值对)
stu = {'name': '张三',
'age': 18,
'gender': '男',
'体重': 160,
'身高': 180}
print(stu['name'])
2.什么是字典
字典是容器型数据类型: 将{}作为容器标志,里面多个键值对用逗号隔开; {键1:值1, 键2:值2, 键3:值3…}
字典是可变的 - 支持增删改
字典是无序的 - 不支持下标操作
元素的要求: 字典元素是键值对
键 - 键必须是不可变的数据(例如:数字、字符串、元组); 键是唯一的;
值 - 没有要求
2-1 空字典
d1 = {}
print(type(d1), len(d1), bool(d1)) # <class 'dict'> 0 False
2-2 键是不可变的数据
d2 = {1: 10, 'a': 20, (10,20): 30} #{1: 10, 'a': 20, (10, 20): 30}
print(d2)
# d3 = {[1,2]: 12} # 列表是可变的,结果报错
2-3 键是唯一的
d4 = {'a': 10, 'b': 20, 'c': 30, 'b': 40}
print(d4) # {'a': 10, 'b': 40, 'c': 30} 不会报错,但数据会缺失
2-4 字典是无序的
print({'a': 10, 'b': 20} == {'b': 20, 'a': 10}) # True 无序
print([10,20] == [20,10]) # False 有序
3. 字典的增删改查
3-1 查 - 获取字典的值
a. 获取单个值
格式:字典[键]
获取字典中指定键对应的值, 如果键不存在,程序会报错
格式:字典.get(键, 默认值=默认值)
返回指定键的值,如果键不在字典中返回 default 设置的默认值
dog = {'name': '旺仔', 'age': 3, 'breed': '哈士奇', 'gender': '公狗', 'color': '黑白'}
print(dog['name'], dog['breed']) # 旺仔 哈士奇
print(dog.get('gender'), dog.get('color')) # 公狗 黑白
# print(dog['']) # 报错,没有这个键
print(dog.get('1', '没这个键')) # 没这个键
b. 遍历
# 通过for循环遍历字典时,变量依次取到的是字典的键
"""
for 键 in 字典:
循环体
"""
for key in dog:
print(key, dog[key])
4.实际应用中的字典和列表
# 定义一个变量保存班级信息
class1 = {
'name': 'python2104',
'address': '23教',
'lecturer': {'name': '余婷', 'age': 18, 'QQ': '726550822'},
'leader': {'name': '舒玲', 'age': 18, 'QQ': '2343844', 'tel': '110'},
'students': [
{'name': 'stu1', 'school': '清华大学', 'tel': '1123', 'linkman': {'name': '张三', 'tel': '923'}},
{'name': 'stu2', 'school': '攀枝花学院', 'tel': '8999', 'linkman': {'name': '李四', 'tel': '902'}},
{'name': 'stu3', 'school': '成都理工大学', 'tel': '678', 'linkman': {'name': '小明', 'tel': '1123'}},
{'name': 'stu4', 'school': '四川大学', 'tel': '9900', 'linkman': {'name': '小花', 'tel': '782'}},
{'name': 'stu5', 'school': '西南交大', 'tel': '665', 'linkman': {'name': '老王', 'tel': '009'}}
]
}
# 1)获取班级名称
# 2)获取讲师QQ
# 3)获取所有学生的名字和学校
# 4)获取所有学生的联系人的电话
print('班级名称:', class1['name']) # 输出班级名称
print('讲师QQ:', class1['lecturer']['QQ']) # 输出讲师QQ
for item in class1['students']:
print('学生名:%s\t学校:%s'%(item['name'], item['school']), end='\t') # 输出所有学生的名字和学校
print('紧急联系人:%s\t电话:%s'%(item['linkman']['name'], item['linkman']['tel'])) # 输出所有学生的联系人的电话
3-2 增和改
格式:字典[键] = 值
当键存在时,作用是修改值;当键不存在时,作用是添加键值对
格式:字典.setdefault(键, 值=默认值)
和get()类似, 但如果键不存在于字典中,将会添加键并将值设为default
dog = {'name':'哈士奇', 'age':5}
print(dog)
# 添加
dog['color'] = '黑白'
dog.setdefault('weight', 8)
print(dog)
# 修改
dog['name'] = '旺仔'
print(dog)
# 练习:在students中没有分数的学生中添加分数对应的键值对,分数值为零
students = [
{'name': 'stu1', 'tel': '1234', 'score': 89},
{'name': 'stu2', 'tel': '465', 'score': 80},
{'name': 'stu3', 'tel': '678'},
{'name': 'stu3', 'score': 78},
{'name': 'stu4', 'tel': '234'}
]
for item in students:
item.setdefault('score', 0)
print(students)
3-3 删 - 删除键值对
格式:del 字典[键]
删除字典中指定键的键值对(如果键不存在会报错)
格式:字典.pop(键)
取出字典中指定键的键值对(存在返回值就是这个键对应的值,如果键不存在会报错)
dog = {'name': '旺仔', 'age': 5, 'color': '黑白', 'weight': 8}
del dog['weight'] # 删除体重
print('删除体重键值对', dog)
age = dog.pop('age')
print('取出删除年龄键值对', dog)
print('取出的年龄值', age)
4. 字典相关操作
字典不支持:+、*、比较大小的运算符;唯一支持:==、!=
in 和 not in - 字典的in 和 not in判断的是键是否存在
键 in 字典
键 not in 字典
5. 相关函数
len
dict(数据) - 1)数据本身是一个序列
2)序列中的元素必须是有且只有两个元素的小序列
3)小序列的第一个元素必须是不可变的数据
data = [('a', 3), ('b', 5), ('c', 8)]
print(dict(data))
data2 = ['ab', range(2), [10, 20]]
print(dict(data2))
# print(dict(['abc', range(3), [10, 20]])) # 会报错,因为'abc'超出了2个元素,range也超了
字典转换成列表/元组 - 取到的只是字典的键
dic2 = {'a': 10, 'b': 20, 'c': 30}
print(list(dic2)) # ['a', 'b', 'c']
6. 字典相关方法
'''
字典.clear() - 清空字典
字典.copy - 复制原字典产生一个一模一样的新字典
字典.update(序列) - 将序列中所有的元素都添加到字典中(如果本身就存在就会覆盖)。序列必须是字典或者能转换成字典的序列
items,keys,values
字典.keys() - 获取字典所有的键,返回一个序列(这个序列不是列表或元组)
'''
data3 = {'d': 100, 'e': 200}
print(dic2) # {'a': 10, 'b': 20, 'c': 30}
dic2.update(data3)
print(dic2) # {'a': 10, 'b': 20, 'c': 30, 'd': 100, 'e': 200}
dic2.update(['xy', 'mn'])
print(dic2) # {'a': 10, 'b': 20, 'c': 30, 'd': 100, 'e': 200}
dic2.update({'d': 1000, 'f': 2000})
print(dic2) # {'a': 10, 'b': 20, 'c': 30, 'd': 1000, 'e': 200, 'x': 'y', 'm': 'n', 'f': 2000}
print(dic2.keys()) # dict_keys(['a', 'b', 'c', 'd', 'e', 'x', 'm', 'f'])
print(dic2.values()) # dict_values([10, 20, 30, 1000, 200, 'y', 'n', 2000])
print(dic2.items()) # dict_items([('a', 10), ('b', 20), ('c', 30), ('d', 1000), ('e', 200), ('x', 'y'), ('m', 'n'), ('f', 2000)])
7. 字典推导式
语法
{键的表达式:值的表达式 for 变量 in 序列}
{键的表达式:值的表达式 for 变量 in 序列 if 条件语句}
# 例子:通过字典的推导式交换一个字典的键和值
data3 = {'d': 100, 'e': 200}
data4 = {data3[key]:key for key in data3}
print(data4.keys(), data4.values())
# dict_keys([100, 200]) dict_values(['d', 'e'])
Ⅲ 课后练习
1.创建一个列表,列表中有10个舒宗, 保证列表中元素的顺序,对列表进行排重,并对列表使用进行降序排序
例如:随机生成了[70, 88, 91, 70, 107, 234, 91, 177, 282, 197]
--- 去重之后 [70, 88, 91, 107, 234, 177, 282, 197]
---- 降序排序 [282, 234, 197, 177, 107, 91, 88, 70]
from random import randint
nums = [randint(0, 300) for i in range(10)]
print('随机原列表', nums)
count = len(nums) - 1
while count > -1 :
if nums.count(nums[count]) > 1:
del nums[count]
count -= 1
nums.sort(reverse=True)
print('删除重复值的列表:', nums)
print('降序后的列表:', nums)
2.利用列表推导式, 完成以下需求
a. 生成一个存放1-100中各位数为3的数据列表
结果为 [3, 13, 23, 33, 43, 53, 63, 73, 83, 93]
nums = [i for i in range(3,100,10)]
print(nums)
b. 利用列表推到是将 列表中的整数提取出来
例如:[True, 17, "hello", "bye", 98, 34, 21] --- [17, 98, 34, 21]
nums = [True, 17, "hello", "bye", 98, 34, 21]
new_nums = [item for item in nums if type(item) == int]
print(new_nums)
c.利用列表推导式 存放指定列表中字符串的长度
例如 ["good", "nice", "see you", "bye"] --- [4, 4, 7, 3]
lists = ["good", "nice", "see you", "bye"]
lists_len = [len(lens) for lens in lists]
print(lists_len)
4.已经一个班级字典如下:
class1 = {
'name': 'python2104',
'address': '23教',
'lecturer': {'name': '余婷', 'age': 18, 'QQ': '726550822'},
'leader': {'name': '舒玲', 'age': 18, 'QQ': '2343844', 'tel': '110'},
'students': [
{'name': 'stu1', 'school': '清华大学', 'tel': '1123', 'age': 18, 'score': 98, 'linkman': {'name': '张三', 'tel': '923'}},
{'name': 'stu2', 'school': '攀枝花学院', 'tel': '8999', 'age': 28, 'score': 76, 'linkman': {'name': '李四', 'tel': '902'}},
{'name': 'stu3', 'school': '成都理工大学', 'tel': '678', 'age': 20, 'score': 53, 'linkman': {'name': '小明', 'tel': '1123'}},
{'name': 'stu4', 'school': '四川大学', 'tel': '9900', 'age': 30, 'score': 87, 'linkman': {'name': '小花', 'tel': '782'}},
{'name': 'stu5', 'school': '西南交大', 'tel': '665', 'age': 22, 'score': 71, 'linkman': {'name': '老王', 'tel': '009'}},
{'name': 'stu6', 'school': '成都理工大学', 'tel': '892', 'age': 32, 'score': 80, 'linkman': {'name': '老王2', 'tel': '0091'}},
{'name': 'stu7', 'school': '四川大学', 'tel': '431', 'age': 17, 'score': 65, 'linkman': {'name': '老王3', 'tel': '0092'}},
{'name': 'stu8', 'school': '攀枝花学院', 'tel': '2333', 'age': 16, 'score': 32, 'linkman': {'name': '老王4', 'tel': '0093'}},
{'name': 'stu9', 'school': '攀枝花学院', 'tel': '565', 'age': 21, 'score': 71, 'linkman': {'name': '老王5', 'tel': '0094'}}
]
}
# 1获取班级位置
print('班级位置:', class1['address'])
# 2)获取班主任的名字和电话
print('班主任的名字:%s\t电话:%s'%(class1['leader']['name'], class1['leader']['tel']))
# 3)获取所有学生的姓名和分数
for item in class1['students']:
print('学生名:%s\t分数:%s'%(item['name'], item['score'])) # 输出所有学生的名字和学校
# 4)获取所有学生联系人的名字和电话
for item in class1['students']:
print('学生联系人:%s\t电话:%s'%(item['linkman']['name'], item['linkman']['tel'])) # 输出所有学生的联系人的电话
# --------------------------------------------------------------------------------------------------------
# 5)获取班级最高分
max1, stu_index, sums = 0, [], 0
# max1:用来得最高分去比较, stu_index:保存最高分学生的下标,列表是防止并列第一; sums:求和用
stu_count = len(class1['students']) # 学生个数
# 遍历每个学生,用下标是为了后续直接获取学生信息
for index in range(stu_count):
# 求班上成绩和
sums += class1['students'][index]['score']
# 比较成绩最高分,等号是为了有并列最高分需保存
if class1['students'][index]['score'] >= max1:
# 作用是清空以前的并列高分,拿到新的最高分后,用保存的最高分下标的元素得到最高分 和 现在这个最高分比较,现在这个最高分大,就清空保存的下标,保存当前最高分
if len(stu_index) and class1['students'][stu_index[0]]['score'] < class1['students'][index]['score']:
stu_index.clear()
# 将当前最高分下标保存
stu_index.append(index)
max1 = class1['students'][index]['score']
for item in stu_index:
print('班上最高分:', class1['students'][item]['score'])
# --------------------------------------------------------------------------------------------------------
# 6)获取班级分数最高的学生的姓名
for item in stu_index:
print('最高分的同学是:', class1['students'][item]['name'])
# 7)计算班级学生的平均分
print('班上的平均分是:%.2f'%(sums / stu_count))
# 8)统计班级中未成年人数
young = 0
for item in class1['students']:
if item['age'] < 18:
young += 1
print('班上未成年有%d人'%(young))
# 9)用字典统计每个学校的人数, 类似: `{'清华大学': 1, '攀枝花学院': 3}`
school_count = {}
for item in class1['students']:
if item['school'] in school_count:
school_count[item['school']] += 1
else:
school_count[item['school']] = 1
print(school_count)