
本文介绍如何准确比较两个无序对象列表是否“完全相等”(即元素一一对应且数量匹配),尤其适用于 ArcGIS 的 Polyline/Geometry 等不支持原生 == 但提供 .equals() 或可序列化属性(如 .JSON)的类。
本文介绍如何准确比较两个无序对象列表是否“完全相等”(即元素一一对应且数量匹配),尤其适用于 arcgis 的 polyline/geometry 等不支持原生 `==` 但提供 `.equals()` 或可序列化属性(如 `.json`)的类。
在实际地理空间开发中(例如使用 ArcPy),我们常遇到 Polyline 或 Geometry 类型的对象——它们虽提供了 .equals() 方法用于几何等价性判断,但该方法不具备传递性与完备计数能力,直接用嵌套循环 + any() 判断会导致误判:当某对象在另一列表中“存在至少一个等价项”时即通过,却忽略了重复次数、多对一匹配等问题(如示例中 foo 出现两次 vs 一次)。
因此,核心思路是:将每个对象映射为唯一、稳定、可哈希的标识符,再基于多重集(multiset)语义进行比较。由于 Geometry 对象支持 .JSON 属性(返回标准化 JSON 字符串),这是理想的哈希依据:
def object_lists_equal(list_a, list_b):
"""
判断两个 Geometry/Polyline 列表是否包含完全相同的几何对象(考虑重复次数)
使用 JSON 字符串作为几何等价性的规范表示
"""
if len(list_a) != len(list_b):
return False
# 将每个几何对象转为 JSON 字符串,并统计频次
from collections import Counter
jsons_a = [obj.JSON for obj in list_a]
jsons_b = [obj.JSON for obj in list_b]
return Counter(jsons_a) == Counter(jsons_b)
def object_lists_not_equal(list_a, list_b):
"""返回 True 当且仅当两列表不完全相等"""
return not object_lists_equal(list_a, list_b)
✅ 优势说明:
让 macOS 自动化像说话一样简单 —— 用代码控制你的 Mac,无需学习 AppleScript 系统要求 macOS 14+ (Sonoma) Python 3.9+ 需要开启:辅助功能 + 屏幕录制权限
-
Counter精确比对每个 JSON 字符串的出现次数,天然支持重复元素; - 避免手动双重循环,时间复杂度从 O(n²) 降至 O(n);
- 利用 ArcGIS 官方推荐的
.JSON属性,语义可靠(几何等价 ⇒ JSON 相同,且实践中 JSON 是确定性序列化结果)。
⚠️ 注意事项:
- 不要使用
set(...)直接比较(如答案中简化版),因为它会丢失重复信息,导致[g1, g1]与[g1]被误判为相等; - 若自定义类未提供
.JSON,请确保实现稳定的__hash__+__eq__,或提供其他可哈希规范表示(如 WKT、WKB、归一化坐标元组); -
.equals()方法在 ArcGIS 中可能受容差(tolerance)影响,而.JSON是精确序列化,二者语义略有差异——若业务要求容忍微小数值误差,应优先使用.equals()并配合itertools.combinations实现二分图最大匹配(较重,需权衡)。
综上,面向生产环境的健壮解法是:以 .JSON(或等效规范序列化)为键,用 Counter 进行频次级相等性校验——简洁、高效、可读性强,且完美契合 ArcGIS 几何对象的特性。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










