【问题标题】:Recursive function to search through a dictionary linked to parallel arrays?递归函数来搜索链接到并行数组的字典?
【发布时间】:2014-03-05 16:21:19
【问题描述】:

我目前正在研究一个递归函数来搜索表示沿河位置的字典。字典使用start作为键索引4个并行数组。

并行数组:

start = 流量累积较小的端点位置,

end = 另一个端点的位置(流量积累较大),

length = 段长度,并且;

shape = 实际形状,定向为从头到尾运行。

字典:

G = {}
for (st,sh,le,en) in zip(start,shape,length,end):
    G[st] = (sh,le,en)

我的目标是从p 表示的起点之一沿河流向下搜索,并选择距离为2000 米(以x 表示)的位置,直到end。这是我正在使用 Python 处理的递归函数:

def Downstream (p, x, G):
...     e = G[p]
...     if (IsNull(e)):
...         return ("Not Found")
...         if (x < 0):
...             return ("Invalid")
...             if (x < e.length):
...                 return (Along (e.shape, x))
...                 return (Downstream (e.end, x-e.length,G))

目前,当我输入 Downstream ("(1478475.0, 12065385.0)", 2000, G) 时,它会返回一个 keyerror。我检查了key in G 并且该键返回false,但是当我搜索G.keys () 时,它返回由start 表示的所有键,包括给出false 的键。

例如,密钥是(1478475.0, 12065385.0)。我已将此键用作文本和 2 个双精度值的元组,并且两次都返回了 keyerror。

错误:

Runtime error
Trackback (most recent call last):
 File “<string>”, line 1, in <module>
 File “<string>”, line 1, in Downstream
KeyError:  (1478475.0, 12065385.0)

是什么导致了密钥错误,我该如何解决这个问题以达到我的目标?

我在 ArcGIS 中使用 Python,因为它使用的是折线 shapefile 中的属性表,这是我第一次尝试使用递归函数。

这个问题和答案是我在组织数据和编写此递归函数时如何达到这一点的。

https://gis.stackexchange.com/questions/87649/select-points-approx-2000-metres-from-another-point-along-a-river

例子:

>>> G.keys ()
[(1497315.0, 11965605.0), (1502535.0, 11967915.0), (1501785.0, 11968665.0)...

>>> print G
{(1497315.0, 11965605.0): (([1499342.3515172896, 11967472.92330054],), (7250.80302528,), (1501785.0, 11968665.0)), (1502535.0, 11967915.0): (([1502093.6057616705, 11968248.26139775],), (1218.82250994,), (1501785.0, 11968665.0)),...

【问题讨论】:

  • dIsNullAlong 是什么?哪条特定的行引发了KeyError?您能否提供一个输入数据和预期输出的最小示例?
  • d 是一个错字,正确的代码是e = G[p],上面已修复。 IsNull 仅返回 0 或 noData 值。输入数据现已添加到问题中。预期输出将是下游间隔距离的坐标。我已经添加了指向我的来源的链接。希望这会有所帮助。
  • 你试过Downstream ((1478475.0, 12065385.0), 2000, G)吗?撇开使用浮点值作为字典键组件这一事实不谈,因为某些小数和非常大的值的表示问题,尤其是在执行任何类型的算术时; the decimal module 对于此类目的会更可靠,但如果您只提供一次 floats 并且它们只能在其元组/存储值列表中访问它们,那么使用 floats 应该不是问题。
  • 是的,我也试过了,但仍然收到 keyerror。

标签: python arrays recursion dictionary keyerror


【解决方案1】:

您的函数无法正常工作有五个主要原因:

  1. 语法不正确 - 缩进在 Python 中很重要;
  2. 您不会在每次调用Downstream 时检查p in G 是否存在(第一个键可能存在,但后面的递归调用呢?);
  3. 你有太多的return 点,例如你的最后一行将永远不会运行(函数输出应该是什么?);
  4. 您似乎正在通过属性 (e.end) 访问三元组 e = (sh, le, en);和
  5. 当您递归调用时,您正在从间隔长度中减去,因此该函数无法跟踪点应该相距多远 - 您需要将间隔和从开始的偏移量分开。

相反,我认为您需要类似(未经测试!):

 def Downstream(start, interval, data, offset=0, out=None):
     if out is None:
         out = []
     if start in data:
         shape, length, end = data[start]
         length = length[0] 
         if interval < length:
             distance = offset
             while distance < length:
                 out.append(Along(shape, distance))
                 distance += interval
             distance -= interval
             Downstream(end, interval, data, interval - (length - distance), out)
         else:
             Downstream(end, interval, data, offset - length, out)
     return out

这将为您提供Along 返回的任何内容的列表。如果是原来的start not in data,会返回一个空列表。

【讨论】:

  • 我建议你输入一些prints 来找出正在处理的数据,然后
  • 我用了函数,输入Downstream ((1497315.0, 11965605.0),2000,G,offset=0,out=None)。输出为[]。我从并行数组中知道,与该键关联的长度为 7250。预期输出的类型是该键在 2000、4000、6000 和 7250 处的坐标。
  • 我尝试了print G,它显示了正在处理的数据,并在上述问题的末尾附加了部分输出。它正在访问三元组G [st] = (sh, le, en)
  • 我已根据您的样本数据对我的答案进行了调整,并获得了我期望的Downstream((1497315.0, 11965605.0), 2000, data) 的输出(我只是append((shape, distance)),因为我没有Along) .尝试将print(start, distance) 放在append 之前,看看到底发生了什么。
  • 我根据您的评论尝试了调整,将打印放在附加之前。我尝试了有和没有Along 函数的代码,所有结果都是空列表[]
猜你喜欢
  • 2018-09-28
  • 2017-11-23
  • 2015-04-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-16
相关资源
最近更新 更多