字典与集合

对应教学日历:讲次 6-7


一、字典(Dictionary)

定义

  • 用大括号 {} 包裹
  • 由**键(key)-值(value)**对构成,用冒号 : 分隔
  • 键必须唯一,必须是不可变数据类型(字符串、数字、元组)
  • 值可以是任意类型
test = {}                           # 空字典
info = {'100001': '张三', '100002': '李四'}
info['100003'] = '王五'              # 新增元素
del info['100002']                   # 删除元素
info['100001'] = '赵六'              # 修改元素值
info['100003']                       # 查看元素值

字典方法

方法功能
keys()返回所有键
values()返回所有值
items()返回所有(键,值)项
get(key, default)返回键对应的值,不存在则返回default
update(a)将字典a中的键值对添加到当前字典
d = {'name': 'alice', 'age': 19, 'sex': 'F'}
d.keys()    # dict_keys(['age', 'sex', 'name'])
d.values()  # dict_values([19, 'F', 'alice'])
d.items()   # dict_items([('age', 19), ('sex', 'F'), ('name', 'alice')])
d.get('name')      # 'alice'
d.get('phone', 0)  # 0(键不存在返回默认值)

字典统计

# 统计字符串中各字符出现次数
str = "13361113355"
adict = {}
for c in str:
    if c not in adict:
        adict[c] = 1
    else:
        adict[c] = adict[c] + 1
print(adict)
 
# 简化写法
for c in str:
    adict[c] = adict.get(c, 0) + 1

counts[word] = counts.get(word, 0) + 1 是最常用的统计模式!

字典遍历

persons = {'name': 'alice', 'age': 19, 'sex': 'F'}
for key, value in persons.items():
    print(f"Key:{key}, Value:{value}")

二、集合(Set)

定义

  • 用大括号 {} 包裹
  • 相当于只有键没有值的字典
  • 元素不可重复不可变无序
aSet = set()              # 空集合(不能用{},那是空字典!)
aSet = {1, 2, 3, 4, 5}
aSet = set('hello')       # {'l', 'e', 'o', 'h'}
aSet = set([1, 'name'])   # {1, 'name'}

集合运算

运算符含义示例
&交集s1 & s2
|并集s1 | s2
-差集s1 - s2
^对称差s1 ^ s2
in成员判断'x' in s1
s1 = {"大米", "榨菜", "鸡肉", "面条"}
s2 = {"大米", "蔬菜", "面条", "猪肉"}
s1 & s2   # {'大米', '面条'}(交集)
s1 | s2   # 所有元素的并集
s1 - s2   # {'鸡肉', '榨菜'}(差集)
s1 ^ s2   # {'蔬菜', '鸡肉', '猪肉', '榨菜'}(对称差)

集合关系判断

s3 = {"大米", "鸡肉"}
s3 <= s1   # True(子集)
s3 >= s2   # False(超集)
s3 < s1    # True(真子集)

集合应用:筛选学生

vSet = {"张飞跃", "李锋", "王蒙", "张池"}    # 会篮球
fSet = {"马霖", "李锋", "张池", "马云"}     # 会足球
sSet = {"李楠", "张池", "张飞跃", "马云"}    # 会踢毽子
result = vSet & fSet - sSet    # 既会篮球又会足球但不会踢毽子
print(result)                   # {'李锋'}

作业示例

爱心词云

from random import *
namelist = ["李文", "何一喆", "林诗诗", "田飞", "袁立"]
counts = {}
for name in namelist:
    counts[name] = randint(30, 100)
 
import matplotlib.pyplot as plt
from wordcloud import WordCloud
from imageio.v2 import imread
pic = imread('love.png')
wc = WordCloud(mask=pic, font_path='msyh.ttc',
    background_color='white', max_words=100,
    random_state=50, scale=1)
wc.generate_from_frequencies(counts)
plt.imshow(wc)
plt.show()

中文文本分析

import jieba
sentence = input("请输入一段文字: ")
result = jieba.lcut(sentence)
counts = {}
for i in result:
    if len(i) == 1:
        continue
    counts[i] = counts.get(i, 0) + 1

要点

  • jieba.lcut() 精确分词,返回列表
  • len(i) == 1 过滤单字词

作业重点

  • 字典用 {key: value} 定义,键必须唯一且不可变
  • counts[word] = counts.get(word, 0) + 1 是统计核心模式
  • 集合用 set() 创建,{} 是空字典不是空集合
  • 集合自动去重,元素无序
  • & 交集、| 并集、- 差集、^ 对称差
  • items() 返回 (key, value) 元组,可用 for k, v in d.items() 遍历