Python集合的创建

一、前言

集合(set)是 Python 中用于去重高效成员判断 的核心数据结构。

但很多初学者在创建集合时就踩了坑:

  • 为什么 {} 不是空集合?
  • 为什么列表不能放进集合?
  • set([1,2,3]){1,2,3} 有什么区别?
  • 如何从字符串、生成器创建集合?

本文将带你: ✅ 掌握 5 种集合创建方式 及其适用场景

✅ 避开 "{} 是字典" 的经典陷阱

✅ 理解 可哈希性 对集合元素的限制

✅ 学会用 集合推导式 高效构建

✅ 写出安全、高效、无 bug 的集合初始化代码


二、方式一:字面量语法(最常用)

使用花括号 {} 直接定义集合(元素用逗号分隔):

python 复制代码
s1 = {1, 2, 3}
s2 = {"apple", "banana", "cherry"}
s3 = {1, "hello", 3.14}  # 元素类型可混合(只要可哈希)

✅ 优点:

  • 语法简洁
  • 执行速度快(无需函数调用)
  • 自动去重

💡 示例:

python 复制代码
s = {1, 2, 2, 3}  # → {1, 2, 3}

⚠️ 重大限制元素必须是可哈希的(如 int、str、tuple),不能是 list、dict、set。


三、方式二:使用 set() 构造器(最灵活)

通过内置函数 set() 从任意可迭代对象创建集合:

python 复制代码
# 从列表(自动去重)
s1 = set([1, 2, 2, 3])      # {1, 2, 3}

# 从字符串(拆分为字符并去重)
s2 = set("hello")           # {'h', 'e', 'l', 'o'}

# 从元组
s3 = set((1, 2, 3))         # {1, 2, 3}

# 从生成器
gen = (x for x in range(5))
s4 = set(gen)               # {0, 1, 2, 3, 4}

# 创建空集合(唯一正确方式!)
empty = set()               # ✅ 空集合

✅ 优势:

  • 支持动态输入(变量、函数返回值等)
  • 适用于任何可迭代对象
  • 创建空集合的唯一标准方式

⚠️ 经典陷阱

python 复制代码
s = {}  # ❌ 这是空字典,不是集合!
print(type(s))  # <class 'dict'>

四、方式三:集合推导式(高级技巧)

类似列表推导式,但结果是集合(自动去重):

python 复制代码
# 提取偶数并去重
evens = {x for x in range(10) if x % 2 == 0}
# {0, 2, 4, 6, 8}

# 从字符串提取大写唯一字母
unique_upper = {c.upper() for c in "Hello World!" if c.isalpha()}
# {'H', 'E', 'L', 'O', 'W', 'R', 'D'}

# 平方去重
squares = {x**2 for x in [1, -1, 2, -2, 3]}
# {1, 4, 9}

✅ 优势:

  • 一行完成过滤 + 转换 + 去重
  • 性能优于先建列表再转集合

五、方式四:从其他集合或 frozenset 创建

python 复制代码
original = {1, 2, 3}
copy_set = set(original)        # 浅拷贝
frozen = frozenset(original)
from_frozen = set(frozen)       # 转回可变集合

✅ 适用场景:集合复制、类型转换


六、方式五:使用 * 解包(Python 3.5+)

从现有可迭代对象解包创建新集合:

python 复制代码
list1 = [1, 2, 3]
list2 = [3, 4, 5]
combined = {*list1, *list2}  # {1, 2, 3, 4, 5}

✅ 优势:快速合并多个序列并去重


七、常见陷阱与避坑指南

❌ 陷阱 1:用 {} 创建空集合

python 复制代码
s = {}          # ❌ 字典
s = set()       # ✅ 集合

📌 记忆口诀"空集合,用 set();非空集,用 {}。"


❌ 陷阱 2:放入不可哈希对象

python 复制代码
# 以下全部报错!
s = {[1, 2]}            # TypeError: unhashable type: 'list'
s = {{"a": 1}}          # dict 不可哈希
s = {{1, 2}}            # set 本身不可哈希

# ✅ 正确:改用元组
s = {(1, 2), (3, 4)}

原则 :集合中的每个元素必须是不可变且可哈希的。


❌ 陷阱 3:误以为字符串会被整体放入

python 复制代码
s = set("abc")   # {'a', 'b', 'c'} ← 拆成字符!
s = {"abc"}      # {'abc'} ← 整个字符串作为一个元素

✅ 区别:

  • set("abc") → 从可迭代对象构建(字符串可迭代)
  • {"abc"} → 字面量,包含一个字符串元素

❌ 陷阱 4:在集合中放 float('nan')

python 复制代码
s = {float('nan'), float('nan')}
print(len(s))  # 2!因为 NaN != NaN

✅ 注意:NaN 在集合中不会被去重(因其不等于自身)


八、性能对比:哪种创建方式最快?

测试创建包含 10 万个整数的集合:

方法 平均耗时(100 次) 说明
{1, 2, ..., n} 最快(但仅适用于静态数据)
set(range(n)) ✅ 快(推荐动态创建)
set([1,2,...,n]) 🐢 较慢(先建列表再转集合,多一次内存分配)
集合推导式 ✅ 快(接近 set(iter)

建议

  • 静态数据 → 用 {...}
  • 动态数据 → 用 set(iterable) 或集合推导式
  • 避免 set(list_literal)(先建列表浪费内存)

九、最佳实践总结

场景 推荐创建方式
非空静态集合 {1, 2, 3}
空集合 set()
从列表/字符串去重 set(my_iterable)
带条件过滤 {x for x in iterable if condition}
合并多个序列 {*seq1, *seq2}
确保元素可哈希 使用 int、str、tuple 等不可变类型

🌈 核心原则
"集合靠哈希实现,元素必须可哈希;空集用 set(),非空可用 {}。"


十、结语

感谢您的阅读!如果你有任何疑问或想要分享的经验,请在评论区留言交流!

相关推荐
xu_yule2 小时前
算法基础-字符串哈希
算法·哈希算法·散列表
LitchiCheng3 小时前
Mujoco 使用 Pinocchio 进行逆动力学及阻抗力矩控制维持当前位置
人工智能·python
殇者知忧3 小时前
凯斯西储(CWRU)数据集解读与数据读取
python·凯斯西储(cwru)数据集
deephub3 小时前
Scikit-Learn 1.8引入 Array API,支持 PyTorch 与 CuPy 张量的原生 GPU 加速
人工智能·pytorch·python·机器学习·scikit-learn
free-elcmacom4 小时前
机器学习高阶教程<11>当数据开始“折叠”:流形学习与深度神经网络如何发现世界的隐藏维度
人工智能·python·神经网络·学习·算法·机器学习·dnn
月明长歌4 小时前
Java数据结构:PriorityQueue堆与优先级队列:从概念到手写大根堆
java·数据结构·python·leetcode·
波克布林的矩阵6334 小时前
VS code为python文件配置默认模板
python
dhdjjsjs4 小时前
Day44 PythonStudy
python
love530love4 小时前
在 PyCharm 中配置 x64 Native Tools Command Prompt for VS 2022 作为默认终端
ide·人工智能·windows·python·pycharm·prompt·comfyui