【问题标题】:How to find next element that matches a previous element within a tolerance in a list of lists?如何在列表列表的容差范围内找到与前一个元素匹配的下一个元素?
【发布时间】:2025-11-26 17:45:01
【问题描述】:

我有一大堆排序的子列表,其中包含如下列表:

biglist = [  
[[25368, 22348], [22348, 21234], [21230, 17750], [17754, 15924], [15924, 14490],[14491, 12780]]   
[[22390, 21242], [10140, 4260], [4260, 2686], [2686, 438]],  
[[14044, 8726], [8762, 4144], [4144, 1420]],  
[[5817, 5097], [5590, 5530], [5304, 2729], [5097, 4430], [3450, 2489], [2729, 1676] , [2489, 1618]]  
]

对于每个子列表 - 理想情况下,

for sublist in biglist:
    for i, element in enumerate(sublist):
         abs(element[i][1] - element [i+1][0]) < 10

例如,子列表[[25368, 22348], [22348, 21234], [21230, 17750], [17754, 15924], [15924, 14490], [14491, 12780] 没有任何问题,因为:

22348 - 22348 = 0  
21234 - 21230 = 4
17750 - 17754 = 4
15924 - 15924 = 0 
14490 - 14491 = 1

所以,如果上述条件 (abs(element[i][1] - element [i+1][0])

例如,在子列表中

[[5817, 5097], [5590, 5530], [5304, 2729], [5094, 4430], [3450, 2489], [2729, 1676], [2489, 1618]]

代码应该打印如下内容:

[5817,5097] matches [5094, 4430] within tolerance of 10 - skipped elements: [5590, 5530], [5304, 2729]
[5304, 2729] matches [2729, 1676] within tolerance of 10 - skipped elements: [5094, 4430], [3450, 2489]
[3450, 2489] matches [2489, 1618] within tolerance of 10 - skipped elements: [2729, 1676] 

如果根本找不到匹配项,则打印:
[5590, 5530] has no match

回答:

我似乎得到了我想要的结果:

for sublist in biglist:
    for i, element in list(enumerate(sublist))[:-1]:
        found = False
        if abs(sublist[i][1] - sublist[i+1][0]) > 10:
            for j in range(i+1, len(sublist)):
                if abs(sublist[i][1] - sublist[j][0]) < 10:
                    print(sublist[i], "matches",  sublist[j], "within tolerance of 10 - skipped elements:", sublist[i+1:j])
                    found = True
                    break
            if not found:
                print(sublist[i], "has no matches")

但是has no matches 给了我错误的结果:

[22390, 21242] has no matches
[14044, 8726] has no matches
[5817, 5097] matches [5097, 4430] within tolerance of 10 - skipped elements: [[5590, 5530] [5304, 2729]]
[5590, 5530] has no matches
[5304, 2729] matches [2729, 1676] within tolerance of 10 - skipped elements: [[5097, 4430], [3450, 2489]]
[5097, 4430] has no matches
[3450, 2489] matches [2489, 1618] within tolerance of 10 - skipped elements: [[2729, 1676]]
[2729, 1676] has no matches

【问题讨论】:

  • 您可以使用scipy.spatial.KDTree 加快速度,仅供参考。

标签: python-3.x list indexing


【解决方案1】:

您几乎完成了,只需在内部创建一个新循环,其中包含 j,从 i 开始,沿途检查匹配并在找到第一个匹配时结束。

biglist = [
    [[25368, 22348], [22348, 21234], [21234, 17750], [17750, 15924], [15924, 14490], [14490, 12780], [12780, 9418], [9418, 7460], [7460, 4884], [4884, 4340]], 
    [[22390, 21242], [10140, 4260], [4260, 2686], [2686, 438]], 
    [[14044, 8726], [8762, 4144], [4144, 1420]], [[5817, 5097], [5590, 5530], [5304, 2729], [5097, 4430], [3450, 2489], [2729, 1676] , [2489, 1618]]
]

for sublist in biglist:
  matched = set()
  for i, element in list(enumerate(sublist))[:-1]:
    found = False
    for j in range(i+1, len(sublist)):
      if abs(sublist[i][1] - sublist[j][0]) < 10:
        print(sublist[i], "matches",  sublist[j], "within tolerance of 10 - skipped elements", sublist[i+1:j])
        matched.add(tuple(sublist[j]))
        found = True
        break
    if not found and tuple(sublist[i]) not in matched:
      print(sublist[i], "has no matches")

结果

[25368, 22348] matches [22348, 21234] within tolerance of 10 - skipped elements []
[22348, 21234] matches [21234, 17750] within tolerance of 10 - skipped elements []
[21234, 17750] matches [17750, 15924] within tolerance of 10 - skipped elements []
[17750, 15924] matches [15924, 14490] within tolerance of 10 - skipped elements []
[15924, 14490] matches [14490, 12780] within tolerance of 10 - skipped elements []
[14490, 12780] matches [12780, 9418] within tolerance of 10 - skipped elements []
[12780, 9418] matches [9418, 7460] within tolerance of 10 - skipped elements []
[9418, 7460] matches [7460, 4884] within tolerance of 10 - skipped elements []
[7460, 4884] matches [4884, 4340] within tolerance of 10 - skipped elements []
[22390, 21242] has no matches
[10140, 4260] matches [4260, 2686] within tolerance of 10 - skipped elements []
[4260, 2686] matches [2686, 438] within tolerance of 10 - skipped elements []
[14044, 8726] has no matches
[8762, 4144] matches [4144, 1420] within tolerance of 10 - skipped elements []
[5817, 5097] matches [5097, 4430] within tolerance of 10 - skipped elements [[5590, 5530], [5304, 2729]]
[5590, 5530] has no matches
[5304, 2729] matches [2729, 1676] within tolerance of 10 - skipped elements [[5097, 4430], [3450, 2489]]
[3450, 2489] matches [2489, 1618] within tolerance of 10 - skipped elements [[2729, 1676]]

【讨论】:

【解决方案2】:

@fizzybear 感谢您的回答:)

我似乎得到了我想要的结果:

for sublist in biglist:
    for i, element in list(enumerate(sublist))[:-1]:
        found = False
        if abs(sublist[i][1] - sublist[i+1][0]) > 10:
            for j in range(i+1, len(sublist)):
                if abs(sublist[i][1] - sublist[j][0]) < 10:
                    print(sublist[i], "matches",  sublist[j], "within tolerance of 10 - skipped elements:", sublist[i+1:j])
                    found = True
                    break
            if not found:
                print(sublist[i], "has no matches")

但是has no matches 给了我错误的结果:

[22390, 21242] has no matches
[14044, 8726] has no matches
[5817, 5097] matches [5097, 4430] within tolerance of 10 - skipped elements: [[5590, 5530] [5304, 2729]]
[5590, 5530] has no matches
[5304, 2729] matches [2729, 1676] within tolerance of 10 - skipped elements: [[5097, 4430], [3450, 2489]]
[5097, 4430] has no matches
[3450, 2489] matches [2489, 1618] within tolerance of 10 - skipped elements: [[2729, 1676]]
[2729, 1676] has no matches

【讨论】:

  • 您应该对旧帖子发表评论,而不是创建新答案。代码可以放在粘贴箱中。 if not found 的缩进减一。
  • @fizzybear 感谢您指出这一点:) 我是 * 和 python 的新手。移动 if not found 语句仍然给我错误的结果。
  • 您正在检查abs(...) 两次。因为ji+1 开始,所以您只需要内部的。
  • 感谢您积极回复 :) 我添加了外部 if 语句 if abs(sublist[i][1] - sublist[i+1][0]) &gt; 10 因为我只想先打印出满足此条件的元素。此外,删除外部 if 语句仍然给我无效的结果:这两个不应该打印:'[2729, 1676] has no matches' - because [5304, 2729] matches [2729, 1676] '[5097, 4430] has no matches' - because [5817, 5097] matches [5097, 4430]
  • 我明白了。匹配也会倒退。检查编辑的答案。
最近更新 更多