Python 使用集合找出两个列表的交集(超详细)

更新时间:

💡一则或许对你有用的小广告

欢迎加入小哈的星球 ,你将获得:专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论

  • 新项目:《从零手撸:仿小红书(微服务架构)》 正在持续爆肝中,基于 Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...点击查看项目介绍 ;
  • 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/ ;

截止目前, 星球 内专栏累计输出 82w+ 字,讲解图 3441+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 2900+ 小伙伴加入学习 ,欢迎点击围观

前言

在编程中,我们常常需要比较两个列表中的元素,找出它们共同拥有的项。例如,电商系统中可能需要比较两个用户的购物车,数据分析时需要筛选出两个数据集的共同样本。虽然可以通过循环遍历逐一比较元素,但这样的方法效率较低,尤其在处理大数据时。

Python 提供了集合(Set)这一数据结构,它天然支持快速的交集运算。本文将从基础概念讲起,结合实际案例,深入探讨如何使用集合高效找出两个列表的交集。无论你是编程初学者还是希望优化代码的中级开发者,都能从中获得实用技巧。


列表与集合:数据结构的本质区别

列表(List)的特点

列表是 Python 中最常用的序列类型之一,具有以下特性:

  1. 有序性:元素按照插入顺序排列,可以通过索引访问。
  2. 可重复性:允许包含重复元素。
  3. 可变性:支持增删改操作。

例如:

shopping_list = ["苹果", "香蕉", "苹果", "橙子"]  
print(shopping_list[0])  # 输出 "苹果"  

集合(Set)的特点

集合是一种无序且唯一的数据结构,其核心特性包括:

  1. 无序性:元素不保存插入顺序。
  2. 唯一性:自动去重,元素不可重复。
  3. 高效性:底层基于哈希表实现,查找、添加和删除操作的时间复杂度均为 O(1)。

例如:

unique_fruits = {"苹果", "香蕉", "橙子"}  
print("香蕉" in unique_fruits)  # 输出 True  

为什么集合适合求交集?

集合的唯一性高效性使其成为求交集的天然选择:

  • 去重特性:自动过滤重复元素,避免冗余计算。
  • 快速查找:通过哈希表实现,查找元素的时间复杂度为 O(1),远快于列表的 O(n)。

交集操作:从基础到进阶

方法 1:使用 intersection() 方法

集合对象提供 intersection() 方法,直接返回两个集合的交集。

步骤说明

  1. 将列表转换为集合。
  2. 调用 intersection() 方法,传入另一个集合。
  3. 将结果转换回列表(可选)。

示例代码

list_a = [1, 2, 3, 4, 5]  
list_b = [4, 5, 6, 7, 8]  

set_a = set(list_a)  
set_b = set(list_b)  

common_elements = set_a.intersection(set_b)  
print(common_elements)  # 输出 {4, 5}  

result_list = list(common_elements)  
print(result_list)  # 输出 [4, 5](顺序可能不同)  

方法 2:使用 & 运算符

集合支持 & 运算符,其功能与 intersection() 完全相同,语法更简洁。

示例代码

common_elements = set_a & set_b  
print(common_elements)  # 输出 {4, 5}  

方法 3:直接操作列表(不推荐)

虽然可以通过双重循环遍历列表元素,但这种方法效率极低,尤其在处理大型数据时:

def find_common(list1, list2):  
    common = []  
    for item in list1:  
        if item in list2 and item not in common:  
            common.append(item)  
    return common  

print(find_common(list_a, list_b))  # 输出 [4, 5]  

性能对比
| 方法 | 时间复杂度 | 适用场景 |
|---------------------|------------|--------------------------|
| 集合操作 | O(n) | 大数据、频繁操作 |
| 双重循环 | O(n²) | 小数据、无需优化 |
| 列表推导式 | O(n²) | 小数据、代码简洁性优先 |


进阶技巧:处理复杂场景

场景 1:嵌套列表的交集

如果列表元素是可变对象(如列表或字典),需要先将其转换为不可变类型(如元组或字符串)。

示例代码

list_a = [[1, 2], [3, 4], [5, 6]]  
list_b = [[3, 4], [7, 8], [5, 6]]  

set_a = {tuple(item) for item in list_a}  
set_b = {tuple(item) for item in list_b}  

common_tuples = set_a & set_b  
common_lists = [list(t) for t in common_tuples]  
print(common_lists)  # 输出 [[3, 4], [5, 6]]  

场景 2:保留原始列表的顺序

集合会打乱元素顺序,若需保留原始列表的顺序,可结合列表推导式:

def ordered_intersection(list1, list2):  
    set2 = set(list2)  
    return [item for item in list1 if item in set2]  

print(ordered_intersection([3, 2, 1], [2, 4, 3]))  # 输出 [3, 2]  

场景 3:处理大数据优化

当列表元素超过百万级时,可以考虑以下优化策略:

  1. 使用生成器表达式减少内存占用。
  2. 结合 set 的快速查找特性,避免不必要的循环。

实战案例:电商系统的商品对比

案例背景

某电商平台需要比较两个店铺的商品列表,找出共同销售的商品。

原始数据

store1_products = ["手机", "耳机", "平板", "耳机", "充电器"]  
store2_products = ["平板", "耳机", "笔记本", "充电器"]  

实现步骤

  1. 去除重复项,转换为集合。
  2. 计算交集。
  3. 输出结果。

代码实现

def find_common_products(store1, store2):  
    set1 = set(store1)  
    set2 = set(store2)  
    common = set1 & set2  
    return list(common)  

common_products = find_common_products(store1_products, store2_products)  
print("共同商品:", common_products)  # 输出 ["耳机", "平板", "充电器"]  

常见问题与解决方案

问题 1:元素不可哈希

如果列表元素是列表、字典等不可哈希的类型,转换为集合时会报错:

list_with_list = [[1, 2], [3, 4]]  
set(list_with_list)  # 报错:unhashable type: 'list'  

解决方法:将元素转换为元组:

set([(1, 2), (3, 4)])  # 合法  

问题 2:空列表的处理

若其中一个列表为空,交集结果也为空集合。需通过条件判断避免后续逻辑出错:

def safe_intersection(list1, list2):  
    set1 = set(list1) if list1 else set()  
    set2 = set(list2) if list2 else set()  
    return set1 & set2  

print(safe_intersection([], ["a"]))  # 输出空集合  

问题 3:类型不一致

若两个列表的元素类型不同(如字符串和整数),交集会过滤所有元素。需统一类型后再处理:

list_a = ["1", "2", "3"]  
list_b = [1, 2, 3]  

common = set(list_a) & set(map(str, list_b))  
print(common)  # 输出 {"1", "2", "3"}  

结论

通过集合操作,我们可以高效、简洁地找到两个列表的交集。本文从基础概念、代码实现到实际案例,逐步展示了这一方法的优势与细节。

  • 核心知识点
    1. 集合的无序性和唯一性使其成为交集运算的最佳工具。
    2. intersection() 方法和 & 运算符是求交集的两种主要方式。
    3. 处理复杂数据类型时,需注意哈希性和类型统一。

希望本文能帮助你掌握这一实用技巧,并在实际开发中提升代码效率。如果遇到具体问题,欢迎在评论区讨论!

最新发布