如何对Rect对象列表排序?基于PymuPDF的PDF阅读器开发问题
解决PymuPDF Rect对象排序问题
问题根源
PymuPDF的Rect对象没有默认实现比较运算符(比如__lt__),直接调用sort()会抛出"无法进行小于比较"的错误。另外你的排序规则是依赖前一个元素的贪心排序,并非全局排序逻辑,无法用普通的sorted()方法直接处理。
解决方案
分两步实现你的排序规则:
- 先选出最靠上且最靠左的Rect作为起始元素;
- 从剩余元素中反复选出与当前最后一个Rect距离最近的元素,直到所有元素处理完毕。
代码实现
import fitz # 导入PymuPDF import math def calculate_rect_distance(rect_a, rect_b): # 计算两个Rect中心的欧氏距离,可根据需求替换为其他距离算法 center_a_x = (rect_a.x0 + rect_a.x1) / 2 center_a_y = (rect_a.y0 + rect_a.y1) / 2 center_b_x = (rect_b.x0 + rect_b.x1) / 2 center_b_y = (rect_b.y0 + rect_b.y1) / 2 return math.hypot(center_a_x - center_b_x, center_a_y - center_b_y) def custom_sort_rects(rect_list): if not rect_list: return [] # 初始化排序结果,先加入最靠上靠左的Rect sorted_result = [] # PymuPDF坐标系中y轴向下递增,y0越小越靠上;x0越小越靠左 first_rect = min(rect_list, key=lambda r: (r.y0, r.x0)) sorted_result.append(first_rect) remaining_rects = [r for r in rect_list if r != first_rect] # 贪心式添加距离最近的Rect while remaining_rects: last_in_result = sorted_result[-1] next_rect = min(remaining_rects, key=lambda r: calculate_rect_distance(last_in_result, r)) sorted_result.append(next_rect) remaining_rects.remove(next_rect) return sorted_result
可选调整
如果不需要中心距离,可替换calculate_rect_distance为其他逻辑:
- 左上角坐标距离:
def calculate_rect_distance(rect_a, rect_b): return math.hypot(rect_a.x0 - rect_b.x0, rect_a.y0 - rect_b.y0)
- 曼哈顿距离(计算更快,适合对性能敏感的场景):
def calculate_rect_distance(rect_a, rect_b): center_a_x = (rect_a.x0 + rect_a.x1) / 2 center_a_y = (rect_a.y0 + rect_a.y1) / 2 center_b_x = (rect_b.x0 + rect_b.x1) / 2 center_b_y = (rect_b.y0 + rect_b.y1) / 2 return abs(center_a_x - center_b_x) + abs(center_a_y - center_b_y)
内容的提问来源于stack exchange,提问作者Dat_guy_who_hangs_out
相关产品推荐
相关产品推荐

