我的Python學習筆記_Day7 字典、集合

字典

1. 什麼是字典

字典(dict)是容器型數據類型,將{}作爲容器的標誌,元素用逗號隔開

字典中的元素是鍵-值對,key:value,缺一不可

{鍵1:值1, 鍵2:值2, 鍵3:值3…}

可變的,無序的(不支持下標操作)

鍵:任何不可變的數據(理論上),實際一般用字符串作爲key,鍵一定是唯一的

值:任何類型的數據

dict1 = {'name':'John', 'age':18, 'gender':'male'}

2. 字典的增刪改查

1) 查
寫法 說明
字典[key] 獲取字典中指定key對應的值
如果key不存在,則報錯
字典.get(key) 獲取字典中指定key對應的值
如果key不存在,返回None
字典.get(key, 默認值) 獲取字典中指定key對應的值
如果key不存在,返回默認值
2) 遍歷
for item in dict1:
    ...

遍歷字典時,遍歷的鍵

原因:

for in循環的原理是先把序列轉換爲列表,在用下標遍歷列表
而字典轉換爲列表只是把鍵放在列表裏

不建議的遍歷方法:

for key, value in dict1.items():
    ...

這種方法的效率非常低!!!

推薦先遍歷鍵,任何用[鍵]取值

3) 增 / 改
寫法 說明
字典[key] = 值 當key存在時,修改指定key對應的值
當key不存在時,添加指定的鍵-值對
4) 刪
寫法 說明
del 字典[key] 刪除字典中指定key對應的鍵-值對
字典.pop(key) 彈出字典中指定key對應的
字典中這一對鍵-值對也會被刪除

隨堂練習:

在這裏插入圖片描述

def solution1(students):
    """第一問解答"""
    num = 0
    for stu in students:
        if stu.get('score') < 60:
            num += 1
    return num


def solution2(students):
    """第二問解答"""
    for stu in students:
        if stu.get('age') < 18:
            print(stu.get('name'))


def solution3(students):
    """第三問解答"""
    for stu in students:
        if stu.get('age') > 25:
            stu['tel'] = '保密'
    return students

3. 運算

==,!=,is

支持上面的三個運算

ps:字典是無序的,== 的結果自悟

不支持+,-,*,/,<,>

4. in / not in

判斷字典中是否有指定的

相當於:

key in 字典 / key not in 字典

5. len,dict

寫法 說明
len(字典) 字典的長度,即鍵-值對的個數
dict(數據) 將指定的數據轉化爲字典
數據要求:
a. 數據本身是序列
b. 序列中的元素也是序列
c. 小序列中的元素有且只有兩個,第一個元素不可變
list1 = [('name', 'Tom'), ('age', 18), ('gender', 'male')]
dict1 = dict(list1)
print(dict1)

6. 字典轉列表

只把 取出來作爲列表的元素

7. 字典和列表的選擇

如果需要保存多個數據,字典和列表的選擇:

數據情況 容器
多個數據是相同意義的數據(數據之間不需要區分) 列表
多個數據意義不同(需要區分) 字典

8. 字典的其他方法

寫法 說明
字典.clear() 清空字典
字典.copy() 拷貝字典,返回新的字典
new_dict =
dict.fromkeys(序列,值)
創建新字典:
序列作爲key
每個key對應的value均爲值
字典.items() 返回字典所有的key和value
返回的數據類型是序列
序列中的元素是兩個元素的元組
分別是key和value
字典.keys() 返回字典所有的key
返回的數據類型是序列
字典.values() 返回字典所有的value
返回的數據類型是序列
字典.setdefault(鍵, 值) 字典中添加鍵-值對
若key已經存在,則不會修改
字典1.update(字典2) 將字典2的所有的鍵-值對更新到字典1中

集合

1. 什麼是集合

集合(dict)容器型數據類型,將{}作爲容器標誌

{元素1, 元素2, 元素3, …}

可變的,無序的(不支持下標操作)

集合中的元素:不可變、唯一(去重)

注意:{}表示空字典,set()才表示空集合

2. 集合中的元素

set1 = {1, 2, 'hash', (10, 2)}  # 不報錯
set2 = {[1, 2], 'hash'}  # 報錯

因爲列表是可變的

3. 集合的增刪改查

1) 查

for 變量 in 集合:
循環體

2) 增
寫法 說明
集合.add(元素) 在集合中添加指定元素
集合.update(序列) 將序列中所有的元素更新到集合中
3) 刪
寫法 說明
集合.remove(元素) 在集合中刪除指定元素
若元素不存在則報錯
集合.discard(元素) 在集合中刪除指定元素
若元素不存在不會報錯
4) 改

沒有改(手動滑稽)

4. 其他相關操作

1) in / not in

同列表

2) len,set

set(序列) - 所有的序列都能轉換成集合(元素不可變),自動去重

3) 程序優化

集合遍歷的效率是最高的,遠比列表高

5. 數學集合運算

並集(|)、交集(&)、差集(-)、對稱差集(^)、>/<(包含關係)

運算方法 寫法 說明
並集 集合1 | 集合2 同數學
交集 集合1 & 集合2 同數學
差集 集合1 - 集合2 同數學
對稱差集 集合1 ^ 集合2 並集 - 交集
包含 集合1 > 集合2 判斷集合1中是否包含集合2

作業

老規矩,先上自己做的,老師答案後面更新

"""
1. 聲明一個字典保存一個學生的信息,學生信息中包括:
姓名、年齡、成績(單科)、電話、性別(男、女、不明)
"""

student1 = {
    'name': 'UZI',
    'age': 18,
    'score': 150,
    'tel': '1111111111',
    'gender': 'male'
}

"""
2. 聲明一個列表,在列表中保存6個學生的信息(6個題1中的字典)
a.統計不及格學生的個數
b.打印不及格學生的名字和對應的成績
c.統計未成年學生的個數
d.打印手機尾號是8的學生的名字
e.打印最高分和對應的學生的名字
f.將列表按學生成績從大到小排序(掙扎一下,不行就放棄)
"""

student2 = {
    'name': '777',
    'age': 12,
    'score': 4396,
    'tel': '1111111112',
    'gender': 'female'
}
student3 = {
    'name': 'Xiao Hu',
    'age': 50,
    'score': 2200,
    'tel': '1111111113',
    'gender': 'male'
}
student4 = {
    'name': 'The Shy',
    'age': 18,
    'score': 9999999,
    'tel': '1111111118',
    'gender': 'God'
}
student5 = {
    'name': 'doinb',
    'age': 18,
    'score': 99999,
    'tel': '1111111115',
    'gender': 'female'
}
student6 = {
    'name': 'Tian',
    'age': 12,
    'score': 9999,
    'tel': '1111111118',
    'gender': 'male'
}

students = [student1,
            student2,
            student3,
            student4,
            student5,
            student6,
            ]


def solution_a():
    """統計不及格學生個數"""
    print('\n==========第一題==========\n')
    sum_num = 0
    for student in students:
        if student['score'] < 4396:
            sum_num += 1
    return sum_num


print(solution_a())


def solution_b():
    """打印不及格學生的名字對應的成績"""
    print('\n==========第二題==========\n')
    for student in students:
        if student['score'] < 4396:
            print(student['name'] + '  ' + str(student['score']))


solution_b()


def solution_c():
    """統計未成年學生個數"""
    print('\n==========第三題==========\n')
    sum_num = 0
    for student in students:
        if student['age'] < 18:
            sum_num += 1
    return sum_num


print(solution_c())


def solution_d():
    """打印手機號尾號是8的學生的名字"""
    print('\n==========第四題==========\n')
    for student in students:
        if student['tel'][-1] == '8':
            print(student['name'])


solution_d()


def solution_e():
    """打印最高分和對應的學生名字"""
    print('\n==========第五題==========\n')
    max_score = float('-inf')
    max_score_player = ''
    for student in students:
        if student['score'] > max_score:
            max_score = student['score']
            max_score_player = student['name']
    return int(max_score), max_score_player


print(solution_e())


def solution_f():
    """將列表按學生成績從大到小排序"""
    print('\n==========第六題==========\n')
    # 依然冒泡排序
    for i in range(len(students)):
        for j in range(len(students) - i - 1):
            if students[j]['score'] < students[j + 1]['score']:
                students[j], students[j + 1] = students[j + 1], students[j]
    return students


print(solution_f())


def solution_g():
    """刪除性別是'God'的學生"""
    print('\n==========第七題==========\n')
    for student in students[:]:
        if student['gender'] == 'God':
            students.remove(student)
    return students


print(solution_g())

"""
3. 用三個列表表示三門學科的選課學生姓名(一個學生可以同時選多門課)
a. 求選課學生總共有多少人
b. 求只選了第一個學科的人的數量和對應的名字
c. 求只選了一門學科的學生的數量和對應的名字
d. 求只選了兩門學科的學生的數量和對應的名字
e. 求選了三門學生的學生的數量和對應的名字
"""

cai = ['UZI', 'baolan', 'sword', 'bang', 'WXZ', '777']
carry = [
    'tian',
    'the shy',
    'doinb',
    'crisp',
    'faker',
    'caps',
    'PDD',
    'white',
    '777',
]
old = [
    '777',
    'faker',
    'UZI',
    'PDD',
    'white',
    'benji',
    'big_nose_without_miss',
    'koro1',
]

set1 = set(cai)
set2 = set(carry)
set3 = set(old)


def solution2a1():
    """求選課學生共有多少人"""
    # 解法1
    sum_players = set1.copy()
    sum_players.update(carry, old)
    return len(sum_players)


print('\n========第二大題的a解法1========\n')

print(solution2a1())


def solution2a2():
    """求選課學生共有多少人"""
    # 解法2
    return len(set1 | set2 | set3)


print('\n========第二大題的a解法2========\n')

print(solution2a2())


def solution2b1(main_list1, list2, list3):
    """求只選了第一個學科的人的數量和對應的名字"""
    # 解法1
    sum_players = 0
    for player in main_list1:
        if player not in list2 and player not in list3:
            print(player)
            sum_players += 1
    return sum_players


print('\n========第二大題的b解法1========\n')

print(solution2b1(cai, carry, old))


def solution2b2():
    """求只選了第一個學科的人的數量和對應的名字"""
    # 解法2
    cai_player = set1 - set2 - set3
    for player in cai_player:
        print(player)
    print(len(cai_player))


print('\n========第二大題的b解法2========\n')

solution2b2()


def solution2c1():
    """求只選了一門學科的學生的數量和對應的名字"""
    # 解法1
    num1 = solution2b1(cai, carry, old)
    num2 = solution2b1(carry, cai, old)
    num3 = solution2b1(old, carry, cai)
    print(num1 + num2 + num3)


print('\n========第二大題的c解法1========\n')

solution2c1()


def solution2c2():
    """求只選了一門學科的學生的數量和對應的名字"""
    # 解法2
    players = (set1 ^ set2 ^ set3) - (set1 & set2 & set3)
    for player in players:
        print(player)
    print(len(players))


print('\n========第二大題的c解法2========\n')

solution2c2()


def solution2d1_fuc1(main_list1, list2, list3):
    """解題輔助函數1"""
    players = set()
    for player in main_list1:
        if (player not in list2 and player in list3) or (
                player in list2 and player not in list3):
            players.add(player)
    return players


def solution2d1():
    """求只選了兩門學科的學生的數量和對應的名字"""
    # 解法1
    players1 = solution2d1_fuc1(cai, carry, old)
    players2 = solution2d1_fuc1(carry, cai, old)
    players3 = solution2d1_fuc1(old, carry, cai)
    players1.update(players2, players3)
    for player in players1:
        print(player)
    print(len(players1))


print('\n========第二大題的d解法1========\n')
solution2d1()


def solution2d2():
    """"求只選了兩門學科的學生的數量和對應的名字"""
    # 解法2
    players = ((set1 & set2) | (set2 & set3) | (set1 & set3)) - \
              (set1 & set2 & set3)
    for player in players:
        print(player)
    print(len(players))


print('\n========第二大題的d解法2========\n')
solution2d2()


def solution2e1():
    """求選了三門學生的學生的數量和對應的名字"""
    sum_num = 0
    for player in cai:
        if player in carry and player in old:
            print(player)
            sum_num += 1
    return sum_num


print('\n========第二大題的e解法1========\n')
print(solution2e1())


def solution2e2():
    """求選了三門學生的學生的數量和對應的名字"""
    players = set1 & set2 & set3
    for player in players:
        print(player)
    print(len(players))


print('\n========第二大題的e解法2========\n')
solution2e2()

作業答案from老師

# 1.聲明一個字典保存一個學生的信息,學生信息包括:姓名,年齡,成績(單科),電話,性別(男女不明)
stu = {'name': '小明', 'age': 18, 'score': 89, 'tel': '1728272333', 'gender': '男'}

# 2.聲明一個列表,在列表中保存6個學生的信息(6個題1中的字典)
students = [
    {'name': '小明', 'age': 18, 'score': 93, 'tel': '1728272338', 'gender': '男'},
    {'name': '小花', 'age': 30, 'score': 56, 'tel': '1728272335', 'gender': '女'},
    {'name': '小紅', 'age': 16, 'score': 89, 'tel': '1728272338', 'gender': '不明'},
    {'name': 'Tom', 'age': 22, 'score': 93, 'tel': '1728272339', 'gender': '男'},
    {'name': '小炮', 'age': 17, 'score': 90, 'tel': '1728272334', 'gender': '女'},
    {'name': '托兒索', 'age': 6, 'score': 30, 'tel': '1728272337', 'gender': '男'}
]
print('=============不及格學生===========')
# a.統計不及格學生的個數
# b.打印不及格學生的名字和對應的成績
count = 0
for stu in students:
    score = stu['score']
    if score < 60:
        count += 1
        print(stu['name'], score)
print('不及格學生的個數:' + str(count))


print('==============未成年學生===============')
# c.統計未成年學生的個數
count = 0
for stu in students:
    if stu['age'] < 18:
        count += 1
print('未成年學生的個數:%d' % count)

# d.打印手機尾號是8的學生的名字
print('手機尾號是8的學生:')
for stu in students:
    if stu['tel'][-1] == '8':
        print(stu['name'])


print('===============最高分==============')
# e.打印最高分和對應的學生的名字
# 方法一:只獲取一個最高分對應的學生
max1 = students[0]    # 將第一個學生的分數設置爲默認的最高分
for stu in students[1:]:
    if stu['score'] > max1['score']:
        max1 = stu
print(max1['score'], max1['name'])

# 方法二: 獲取同時爲最高分的多個學生
# [80, 79, 80, 84, 85, 70, 85]
"""
max_score= 85
max_students = [4, 6]
"""
max_score = students[0]['score']   # 最大分數
max_students = [students[0]['name']]       # 最高分對應的所有的學生的名字
for stu in students[1:]:
    # 如果分數和最高分相等:就將名字直接添加到列表中
    if stu['score'] == max_score:
        max_students.append(stu['name'])

    # 如果分數大於最高分, 清空原來的最高分對應的名字,添加新的名字
    elif stu['score'] > max_score:
        max_score = stu['score']
        max_students.clear()
        max_students.append(stu['name'])

print('最高分{}, 對應的學生有:{}'.format(max_score, str(max_students)[1:-1]))

# f.將列表按學生成績從大到小排序(掙扎一下,不行就放棄)
# 方法一: 高階函數
# students.sort(reverse=True, key=lambda item: item['score'])
# print(students)

# 方法二: 選擇排序:
"""
第一輪: 獲取整個序列中的最小值放到第一位
第二輪: 從除了第一位以外的元素中選出第二小的值放到第二位
...
"""
# nums = [8, 3, 5, 1]
# length = len(nums)
# for index1 in range(length-1):
#     for index2 in range(index1+1, length):
#         if nums[index2] > nums[index1]:
#             nums[index1], nums[index2] = nums[index2], nums[index1]
# print(nums)

length = len(students)
for index1 in range(length-1):
    for index2 in range(index1+1, length):
        if students[index2]['score'] > students[index1]['score']:
            students[index1], students[index2] = students[index2], students[index1]

print(students)

# g.刪除性別不明的所有學生
for stu in students[:]:
    if stu['gender'] == '不明':
        students.remove(stu)
print(students)

# 3.用三個列表表示三門學科的選課學生姓名(一個學生可以同時選多門課)
python = {'stu1', 'stu2', 'stu5', 'stu6', 'stu8', 'stu9'}
java = {'stu1', 'stu3', 'stu4', 'stu6'}
h5 = {'stu1', 'stu3', 'stu5', 'stu6', 'stu7', 'stu9'}
# 	a. 求選課學生總共有多少人
set1 = python | java | h5
print('選課所有學生:', set1)

#  	b. 求只選了第一個學科的人的數量和對應的名字
set2 = python - java - h5
print('第一個學科的人的名字:', set2)

# 	e. 求選了三門學生的學生的數量和對應的名字
set3 = python & java & h5
print('選了三門學生的學生:', set3)

#  	d. 求只選了兩門學科的學生的數量和對應的名字
set4 = ((python & java) | (python & h5) | (java & h5)) - set3
print('只選了兩門學科的學生:', set4)

# 	c. 求只選了一門學科的學生的數量和對應的名字
set5 = set1 - set3 - set4
print('只選了一門學科的學生:', set5)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章