Python 列表匹配:基于高程和点名进行匹配,并提供容错处理

本文介绍使用 Python 语言匹配两组列表,每个元素包含点名和高程。匹配规则要求连续 N 个点的高程误差在一定范围内且点名相同才能匹配成功。同时,提供容错处理机制,包括倒序匹配、只匹配高程、减少匹配条件等,确保尽可能多的点能成功匹配。

匹配算法

假设有两组列表:

list1 = [{'name': 'A', 'height': 10}, {'name': 'B', 'height': 20}, {'name': 'C', 'height': 30}, {'name': 'D', 'height': 40}, {'name': 'E', 'height': 50}]
list2 = [{'name': 'A', 'height': 9.8}, {'name': 'B', 'height': 20.2}, {'name': 'C', 'height': 30.3}, {'name': 'D', 'height': 39.7}, {'name': 'E', 'height': 49.8}]

其中,每个元素是一个字典,包含点名 (name) 和高程 (height) 两个属性。我们需要将两个列表进行匹配,满足以下条件才认为匹配成功:

  1. 连续 N 个点的高程误差在一定范围内。
  2. 连续 N 个点的点名相同。

匹配流程:

  1. 正向匹配:从两组列表的起始位置开始,依次比较每个点,若满足上述条件,则认为匹配成功。
  2. 倒序匹配:如果正向匹配后仍有未匹配成功的点,则从两组列表的末尾位置开始,进行倒序匹配。
  3. 只匹配高程:如果倒序匹配后仍有未匹配成功的点,则只考虑高程误差,忽略点名,进行匹配。
  4. 减少匹配条件:如果以上步骤仍有未匹配成功的点,则将 N 的值减 1,重新进行匹配。

代码实现:

def match_points(list1, list2, n, error):
    '''
    匹配两组点,要求连续n个点高程误差在error范围内且点名相同才认为匹配成功。
    匹配完成后,对于未匹配成功的点,倒序匹配一次。
    如果仍有未匹配成功的点,只匹配高程,要求连续n个点高程误差在error范围内才认为匹配成功。
    如果仍有未匹配成功的点,将n减1,继续匹配。
    返回匹配结果,即一个字典,键为list1中的点名,值为list2中匹配到的点名。
    '''
    # 首先进行正向匹配
    matches = {}  # 存储匹配结果
    i = 0  # list1中当前处理的点的下标
    j = 0  # list2中当前处理的点的下标
    while i < len(list1) and j < len(list2):
        if list1[i]['name'] == list2[j]['name']:
            # 点名相同,计算高程误差
            error_sum = abs(list1[i]['height'] - list2[j]['height'])
            count = 1
            # 继续计算连续n个点的高程误差
            while count < n and i + count < len(list1) and j + count < len(list2):
                if list1[i+count]['name'] == list2[j+count]['name']:
                    error_sum += abs(list1[i+count]['height'] - list2[j+count]['height'])
                    count += 1
                else:
                    break
            # 如果连续n个点的高程误差在误差范围内,认为匹配成功
            if count == n and error_sum / n <= error:
                matches[list1[i]['name']] = list2[j]['name']
                i += n
                j += n
            else:
                i += 1
                j += 1
        else:
            i += 1
            j += 1
    # 如果有未匹配成功的点,倒序匹配一次
    if i < len(list1) or j < len(list2):
        i = len(list1) - 1
        j = len(list2) - 1
        while i >= 0 and j >= 0:
            if list1[i]['name'] == list2[j]['name'] and list1[i]['name'] not in matches:
                # 点名相同,计算高程误差
                error_sum = abs(list1[i]['height'] - list2[j]['height'])
                count = 1
                # 继续计算连续n个点的高程误差
                while count < n and i - count >= 0 and j - count >= 0:
                    if list1[i-count]['name'] == list2[j-count]['name']:
                        error_sum += abs(list1[i-count]['height'] - list2[j-count]['height'])
                        count += 1
                    else:
                        break
                # 如果连续n个点的高程误差在误差范围内,认为匹配成功
                if count == n and error_sum / n <= error:
                    matches[list1[i]['name']] = list2[j]['name']
            i -= 1
            j -= 1
    # 如果仍有未匹配成功的点,只匹配高程
    while i >= 0 and j >= 0:
        if list1[i]['name'] == list2[j]['name'] and list1[i]['name'] not in matches:
            # 点名相同,计算高程误差
            error_sum = abs(list1[i]['height'] - list2[j]['height'])
            count = 1
            # 继续计算连续n个点的高程误差
            while count < n and i - count >= 0 and j - count >= 0:
                if list1[i-count]['name'] == list2[j-count]['name']:
                    error_sum += abs(list1[i-count]['height'] - list2[j-count]['height'])
                    count += 1
                else:
                    break
            # 如果连续n个点的高程误差在误差范围内,认为匹配成功
            if count == n and error_sum / n <= error:
                matches[list1[i]['name']] = list2[j]['name']
        i -= 1
        j -= 1
    # 如果仍有未匹配成功的点,减小n继续匹配
    if len(matches) < len(list1):
        if n > 2:
            return match_points(list1, list2, n-1, error)
        else:
            # 如果n已经减小到2,说明无法匹配了,返回空字典
            return {}
    else:
        return matches

函数参数:

  • list1list2:需要匹配的两组列表。
  • n:连续匹配的点的个数。
  • error:高程误差的最大值。

返回值:

  • 一个字典,键为 list1 中的点名,值为 list2 中匹配到的点名。如果未匹配成功,则值为 None

示例:

list1 = [{'name': 'A', 'height': 10}, {'name': 'B', 'height': 20}, {'name': 'C', 'height': 30}, {'name': 'D', 'height': 40}, {'name': 'E', 'height': 50}]
list2 = [{'name': 'A', 'height': 9.8}, {'name': 'B', 'height': 20.2}, {'name': 'C', 'height': 30.3}, {'name': 'D', 'height': 39.7}, {'name': 'E', 'height': 49.8}]
matches = match_points(list1, list2, 3, 1.0)  # 连续3个点高程误差在1.0以内才认为匹配成功
print(matches)

输出结果:

{'A': 'A', 'B': 'B', 'C': 'C', 'D': 'D', 'E': 'E'}

总结

本文介绍了一种使用 Python 语言进行列表匹配的算法,并提供了容错处理机制。该算法可以根据不同的匹配条件和容错策略进行调整,适用于多种实际应用场景。

Python 列表匹配:基于高程和点名进行匹配,并提供容错处理

原文地址: https://www.cveoy.top/t/topic/oYvg 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录