Python基础 : 常用数据结构---集合&字典

注:参考骆昊的Python - 100天从新手到大师项目笔记

1. 集合

集合的特点

  • 无序性(不支持索引运算)
  • 互异性(集合中不存在重复元素,具有去重特性)
  • 确定性(成员运算)

创建集合

  • {}

  • 构造器语法 set

  • 生成式语法

    # 创建集合的字面量语法(重复元素不会出现在集合中)
    set1 = {1, 2, 3, 3, 3, 2}
    print(set1)         # {1, 2, 3}
    print(len(set1))    # 3
    
    # 创建集合的构造器语法(后面会讲到什么是构造器)
    set2 = set('hello')
    print(set2)         # {'h', 'l', 'o', 'e'}
    # 将列表转换成集合(可以去掉列表中的重复元素)
    set3 = set([1, 2, 3, 3, 2, 1])
    print(set3)         # {1, 2, 3}
    
    # 创建集合的生成式语法(将列表生成式的[]换成{})
    set4 = {num for num in range(1, 20) if num % 3 == 0 or num % 5 == 0}
    print(set4)         # {3, 5, 6, 9, 10, 12, 15, 18}
    
    # 集合元素的循环遍历
    for elem in set4:
        print(elem)
    
    

    集合中的元素必须是hashable类型
    通常不可变类型都是hashable类型,如整数、浮点、字符串、元组等
    可变类型都不是hashable类型,集合本身也是可变类型,所以不能够作为集合中的元素

集合的运算

成员运算
  • in

  • not in

    set1 = {11, 12, 13, 14, 15}
    print(10 in set1)        # False 
    print(15 in set1)        # True
    set2 = {'Python', 'Java', 'Go', 'Swift'}
    print('Ruby' in set2)    # False
    print('Java' in set2)    # True
    
交并差运算
  • 交集:&、intersection

  • 并集:|、union

  • 差集:-、difference

  • 对称差:^、symmetric_difference

    set1 = {1, 2, 3, 4, 5, 6, 7}
    set2 = {2, 4, 6, 8, 10}
    
    # 交集
    # 方法一: 使用 & 运算符
    print(set1 & set2)                # {2, 4, 6}
    # 方法二: 使用intersection方法
    print(set1.intersection(set2))    # {2, 4, 6}
    
    # 并集
    # 方法一: 使用 | 运算符
    print(set1 | set2)         # {1, 2, 3, 4, 5, 6, 7, 8, 10}
    # 方法二: 使用union方法
    print(set1.union(set2))    # {1, 2, 3, 4, 5, 6, 7, 8, 10}
    
    # 差集
    # 方法一: 使用 - 运算符
    print(set1 - set2)              # {1, 3, 5, 7}
    # 方法二: 使用difference方法
    print(set1.difference(set2))    # {1, 3, 5, 7}
    
    # 对称差
    # 方法一: 使用 ^ 运算符
    print(set1 ^ set2)                        # {1, 3, 5, 7, 8, 10}
    # 方法二: 使用symmetric_difference方法
    print(set1.symmetric_difference(set2))    # {1, 3, 5, 7, 8, 10}
    # 方法三: 对称差相当于两个集合的并集减去交集
    print((set1 | set2) - (set1 & set2))      # {1, 3, 5, 7, 8, 10}
    
    
比较运算
  • 子集:<

  • 真子集:<=

  • 超集:>

    set1 = {1, 3, 5}
    set2 = {1, 2, 3, 4, 5}
    set3 = set2
    # <运算符表示真子集,<=运算符表示子集
    print(set1 < set2, set1 <= set2)    # True True
    print(set2 < set3, set2 <= set3)    # False True
    # 通过issubset方法也能进行子集判断
    print(set1.issubset(set2))      # True
    
    # 反过来可以用issuperset或>运算符进行超集判断
    print(set2.issuperset(set1))    # True
    print(set2 > set1)              # True
    
    

集合的方法

  • 添加元素

    • add
  • 删除元素

    • discard(常用)
    • remove(先验证)
    • pop(随机)
    • clear(全清)
  • 判断两集合是否具有相同的元素

    • isdisjoint
    # 创建一个空集合
    set1 = set()
    # 通过add方法添加元素
    set1.add(33)
    set1.add(55)
    set1.update({1, 10, 100, 1000})
    print(set1)    # {33, 1, 100, 55, 1000, 10}
    
    # 通过discard方法删除指定元素
    set1.discard(100)
    set1.discard(99)
    print(set1)    # {1, 10, 33, 55, 1000}
    # 通过remove方法删除指定元素,建议先做成员运算再删除
    # 否则元素如果不在集合中就会引发KeyError异常
    if 10 in set1:
        set1.remove(10)
    print(set1)    # {33, 1, 55, 1000}
    
    # pop方法可以从集合中随机删除一个元素并返回该元素
    print(set1.pop())
    
    # clear方法可以清空整个集合
    set1.clear()
    print(set1)    # set()
    
    # 判断两个集合有没有相同的元素
    set1 = {'Java', 'Python', 'Go', 'Kotlin'}
    set2 = {'Kotlin', 'Swift', 'Java', 'Objective-C', 'Dart'}
    set3 = {'HTML', 'CSS', 'JavaScript'}
    print(set1.isdisjoint(set2))    # False
    print(set1.isdisjoint(set3))    # True
    
    
  • 不可变集合:

    • frozenset

2. 字典

创建字典

  • {键:键值}

  • 内置函数dict
    直接创造字典
    将两个序列匹配为字典

  • 字典生成语

    #  {键:键值}
    person = {
        'name': '王大锤', 'age': 55, 'weight': 60, 'office': '科华北路62号', 
        'home': '中同仁路8号', 'tel': '13122334455', 'econtact': '13800998877'
    }
    print(person)
    
    # dict函数(构造器)中的每一组参数就是字典中的一组键值对
    person = dict(name='王大锤', age=55, weight=60, home='中同仁路8号')
    print(person)    # {'name': '王大锤', 'age': 55, 'weight': 60, 'home': '中同仁路8号'}
    
    # 可以通过Python内置函数zip压缩两个序列并创建字典
    items1 = dict(zip('ABCDE', '12345'))
    print(items1)    # {'A': '1', 'B': '2', 'C': '3', 'D': '4', 'E': '5'}
    items2 = dict(zip('ABCDE', range(1, 10)))
    print(items2)    # {'A': 1, 'B': 2, 'C': 3, 'D': 4, 'E': 5}
    
    # 用字典生成式语法创建字典
    items3 = {x: x ** 3 for x in range(1, 6)}
    print(items3)     # {1: 1, 2: 8, 3: 27, 4: 64, 5: 125}
    
    

字典的运算

  • 成员运算

  • 索引运算(索引的是键值中的键)

  • 修改(增加新的键值对、修改对应键对应的键值)

  • 输出键值对的数量

  • 输出键值对的格式

    person = {'name': '王大锤', 'age': 55, 'weight': 60, 'office': '科华北路62号'}
    
    # 成员运算
    print('name' in person, 'tel' in person)    # True False
    
    # 修改键值
    if 'age' in person:
        person['age'] = 25
        
    # 存入新的键值对
    person['tel'] = '13122334455'
    person['signature'] = '你的男朋友是一个盖世垃圾,他会踏着五彩祥云去赢取你的闺蜜'
    print('name' in person, 'tel' in person)    # True True
    
    # 检查person字典中键值对的数量
    print(len(person))    # 6
    
    # 输出键值对
    for key in person:
        print(f'{key}: {person[key]}')
    	'''
    	name: 王大锤
    	age: 25
    	weight: 60
    	office: 科华北路62号
    	tel: 13122334455
    	signature: 你的男朋友是一个盖世垃圾,他会踏着五彩祥云去赢取你的闺蜜
    	'''
    print(person)  #{'name': '王大锤', 'age': 25, 'weight': 60, 'office': '科华北路62号', 'tel': '13122334455', 'signature': '你的男朋友是一个盖世垃圾,他会踏着五彩祥云去赢取你的闺蜜'}
    
    

字典的方法

字典的嵌套
获取字典的相应数据
  • get:通过键获得对应的值
  • keys:获得所有的键
  • values:获得所有的值
  • items:获得所有的键值对
  • for key, value in students.items:遍历循环
删除字典中的元素
  • pop:删除键,并返回该值
  • popitem:删除字典中最后一组键值,并返回该二元组
  • setdefault:更新字典元素,相同键更新值,不同键则添加
  • update:更新字典元素,相同键更新值,不同键则添加
  • del:删除元素
# 字典中的值又是一个字典(嵌套的字典)
students = {
    1001: {'name': '狄仁杰', 'sex': True, 'age': 22, 'place': '山西大同'},
    1002: {'name': '白元芳', 'sex': True, 'age': 23, 'place': '河北保定'},
    1003: {'name': '武则天', 'sex': False, 'age': 20, 'place': '四川广元'}
}

# 使用get方法通过键获取对应的值,如果取不到不会引发KeyError异常而是返回None或设定的默认值
print(students.get(1002))    # {'name': '白元芳', 'sex': True, 'age': 23, 'place': '河北保定'}
print(students.get(1005))    # None
print(students.get(1005, {'name': '无名氏'}))    # {'name': '无名氏'}

# 获取字典中所有的键
print(students.keys())      # dict_keys([1001, 1002, 1003])
# 获取字典中所有的值
print(students.values())    # dict_values([{...}, {...}, {...}])
# 获取字典中所有的键值对
print(students.items())     # dict_items([(1001, {...}), (1002, {....}), (1003, {...})])
# 对字典中所有的键值对进行循环遍历
for key, value in students.items():
    print(key, '--->', value)

# 使用pop方法通过键删除对应的键值对并返回该值
stu1 = students.pop(1002)
print(stu1)             # {'name': '白元芳', 'sex': True, 'age': 23, 'place': '河北保定'}
print(len(students))    # 2
# stu2 = students.pop(1005)    # KeyError: 1005
stu2 = students.pop(1005, {})
print(stu2)             # {}

# 使用popitem方法删除字典中最后一组键值对并返回对应的二元组
# 如果字典中没有元素,调用该方法将引发KeyError异常
key, value = students.popitem()
print(key, value)    # 1003 {'name': '武则天', 'sex': False, 'age': 20, 'place': '四川广元'}

# setdefault可以更新字典中的键对应的值或向字典中存入新的键值对
# setdefault方法的第一个参数是键,第二个参数是键对应的值
# 如果这个键在字典中存在,更新这个键之后会返回原来与这个键对应的值
# 如果这个键在字典中不存在,方法将返回第二个参数的值,默认为None
result = students.setdefault(1005, {'name': '方启鹤', 'sex': True})
print(result)        # {'name': '方启鹤', 'sex': True}
print(students)      # {1001: {...}, 1005: {...}}

# 使用update更新字典元素,相同的键会用新值覆盖掉旧值,不同的键会添加到字典中
others = {
    1005: {'name': '乔峰', 'sex': True, 'age': 32, 'place': '北京大兴'},
    1010: {'name': '王语嫣', 'sex': False, 'age': 19},
    1008: {'name': '钟灵', 'sex': False}
}
students.update(others)
print(students)      # {1001: {...}, 1005: {...}, 1010: {...}, 1008: {...}}

person = {'name': '王大锤', 'age': 25, 'sex': True}
del person['age']
print(person)    # {'name': '王大锤', 'sex': True}

字典的应用

统计每个英文字母出现的次数
sentence = input('请输入一段话: ')
counter = {}
for ch in sentence:
    if 'A' <= ch <= 'Z' or 'a' <= ch <= 'z':
        counter[ch] = counter.get(ch, 0) + 1
for key, value in counter.items():
    print(f'字母{key}出现了{value}次.')

找出股价大于100元的股票
# 在一个字典中保存了股票的代码和价格,找出股价大于100元的股票并创建一个新的字典

stocks = {
    'AAPL': 191.88,
    'GOOG': 1186.96,
    'IBM': 149.24,
    'ORCL': 48.44,
    'ACN': 166.89,
    'FB': 208.09,
    'SYMC': 21.29
}
stocks2 = {key: value for key, value in stocks.items() if value > 100}
print(stocks2)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值