飞翔飞翔
主页
  • 计算机基础

    • TCP/IP协议
    • Linux命令
  • 数据库

    • SQL教程
  • 编程语言

    • C语言
    • Python2
    • Python3
  • 数据格式

    • JSON教程
  • 工具

    • Markdown指南
  • Git

    • GitFlow
  • Quartz

    • Quartz教程
  • Java

    • Java设计模式
  • 缓存

    • Redis教程
联系
阿里云
主页
  • 计算机基础

    • TCP/IP协议
    • Linux命令
  • 数据库

    • SQL教程
  • 编程语言

    • C语言
    • Python2
    • Python3
  • 数据格式

    • JSON教程
  • 工具

    • Markdown指南
  • Git

    • GitFlow
  • Quartz

    • Quartz教程
  • Java

    • Java设计模式
  • 缓存

    • Redis教程
联系
阿里云
  • 学习路径
  • 第1章 认识Python

    • Python 历史与特点
    • Python 2 与 Python 3 的核心差异
    • 安装与运行 Python 2.7.18
    • 编码规范 PEP 8
  • 第2章 基础语法

    • 变量与对象
    • 数字类型
    • 字符串 str
    • Unicode 字符串
    • 运算符
    • 空值 None
  • 第3章 流程控制

    • if 条件语句
    • if-else 条件语句
    • if-elif-else 多分支
    • 条件表达式(三元运算符)
    • while 循环
    • for 循环
    • range 与 xrange
    • 循环控制:break、continue、pass
    • 循环 else 子句
  • 第4章 数据结构

    • 列表基础
    • 列表方法
    • 列表推导式
    • 元组
    • 字典基础
    • 字典方法
    • 字典循环技巧
    • 集合
    • 序列解包
    • 序列比较
  • 第5章 函数

    • 定义函数
    • 参数传递机制
    • 默认参数
    • 关键字参数
    • 可变参数
    • Lambda 表达式
    • 文档字符串
    • 函数对象
  • 第6章 模块与包

    • import 导入
    • 模块搜索路径
    • name 与主程序
    • 编译文件 .pyc 与 .pyo
    • 包结构
    • dir() 函数
  • 第7章 文件与IO

    • 打开与关闭文件
    • 文件读写方法
    • with 上下文管理器
    • 格式化输出:% 操作符
    • 格式化输出:str.format()
    • JSON 序列化
  • 第8章 面向对象

    • 类定义与实例化
    • init 构造方法
    • 类变量与实例变量
    • 方法调用与 self
    • 继承基础
    • 多重继承
    • 新式类与旧式类
    • 私有变量与名称改写
    • 属性装饰器 property
    • 类方法与静态方法
    • 魔术方法
    • 空类与数据记录
  • 第9章 异常处理

    • 异常类型
    • try-except
    • try-except-else-finally
    • 抛出异常 raise
    • 自定义异常
    • with 语句与上下文管理器
  • 第10章 迭代器与生成器

    • 迭代器协议
    • 生成器函数
    • 生成器表达式
    • itertools模块
  • 第11章 标准库精要

    • os模块
    • sys模块
    • datetime模块
    • re模块
    • json模块
    • collections模块
    • math与random模块
    • urllib2与网络请求
    • subprocess与命令执行
    • threading与并发
    • unittest与测试
    • 虚拟环境与包管理
  • 第12章 工程实践

    • 调试技巧
    • 性能分析
    • 文档与注释
    • 下一步学习

集合

集合(set)是一种无序、不重复的元素集合。它支持数学中的集合运算:并集、交集、差集、对称差集。集合中的元素必须是不可变(可哈希)的对象。

创建集合

# 用花括号(注意:空 {} 是字典,不是集合)
s = {1, 2, 3, 3, 3}
print s             # set([1, 2, 3]),重复自动去重

# 用 set() 构造函数
s = set([1, 2, 3, 3])
print s             # set([1, 2, 3])

# 空集合(必须用 set())
empty = set()
print type(empty)   # <type 'set'>

not_set = {}        # 这是空字典!
print type(not_set) # <type 'dict'>

添加和删除元素

s = {1, 2, 3}

# 添加单个元素
s.add(4)
print s             # set([1, 2, 3, 4])

# 添加已存在的元素,无效果
s.add(3)
print s             # set([1, 2, 3, 4])

# 删除元素
s.remove(3)
print s             # set([1, 2, 4])

# remove 不存在的元素会报错
s.remove(10)        # KeyError: 10

# discard:删除元素,不存在不报错
s.discard(10)
print s             # 无变化

# pop():删除并返回任意元素
item = s.pop()
print item          # 1(或其他元素,顺序不确定)

# clear():清空
s.clear()
print s             # set([])

集合运算

a = {1, 2, 3, 4}
b = {3, 4, 5, 6}

# 并集:在 a 或 b 中的元素
print a | b         # set([1, 2, 3, 4, 5, 6])
print a.union(b)    # 同上

# 交集:同时在 a 和 b 中的元素
print a & b         # set([3, 4])
print a.intersection(b)  # 同上

# 差集:在 a 中但不在 b 中的元素
print a - b         # set([1, 2])
print a.difference(b)      # 同上

# 对称差集:只在 a 或只在 b 中的元素
print a ^ b         # set([1, 2, 5, 6])
print a.symmetric_difference(b)  # 同上

# 子集和超集
print a <= b        # False,a 不是 b 的子集
print {3, 4} <= a   # True
print a >= {1, 2}  # True

实际应用

去重:

nums = [1, 2, 2, 3, 3, 3, 4]
unique = list(set(nums))
print unique        # [1, 2, 3, 4](顺序可能不同)

注意:set 不保留顺序。如果需要去重且保留顺序,用普通循环或 collections.OrderedDict:

# 保留顺序的去重
seen = set()
result = []
for x in nums:
    if x not in seen:
        seen.add(x)
        result.append(x)
print result        # [1, 2, 3, 4]

成员检测:

# 列表查找是 O(n)
large_list = range(1000000)
print 999999 in large_list      # 慢,需要遍历

# 集合查找是 O(1)
large_set = set(large_list)
print 999999 in large_set       # 快,哈希查找

关系判断:

# 两个列表是否有共同元素
list1 = [1, 2, 3]
list2 = [3, 4, 5]

# 低效:O(n*m)
has_common = any(x in list2 for x in list1)

# 高效:O(n+m)
has_common = not set(list1).isdisjoint(list2)

集合推导式

与列表推导式类似:

# 平方集合(自动去重)
squares = {x**2 for x in range(10)}
print squares       # set([0, 1, 4, 81, 64, 9, 16, 49, 25, 36])

# 过滤
odds = {x for x in range(20) if x % 2 == 1}
print odds          # set([1, 3, 5, 7, 9, 11, 13, 15, 17, 19])

不可变集合 frozenset

frozenset 是不可变的集合,创建后不能添加或删除元素。因此它可以作为字典的键或另一个集合的元素:

# frozenset 作为字典键
locations = {
    frozenset(["a", "b"]): "edge AB",
    frozenset(["b", "c"]): "edge BC",
}

# 普通 set 不能作为键
# d = {set([1, 2]): "A"}    # TypeError: unhashable type: 'set'

# frozenset 支持所有查询操作,不支持修改
fs = frozenset([1, 2, 3])
print 2 in fs       # True
print fs | {3, 4}   # frozenset([1, 2, 3, 4])
# fs.add(5)         # AttributeError: 'frozenset' object has no attribute 'add'

集合 vs 列表 vs 字典

特性列表集合字典
有序是否否(Python 2)
重复允许不允许键不允许
查找O(n)O(1)O(1)
用途序列数据去重、关系运算键值映射
上一页
字典循环技巧
下一页
序列解包