2017-08-02 97 views
-2

我有一个简单的脚本使用GyPython组件Rhino/Grasshopper。目标是将小时天气数据(只记录几小时)分配到几小时。如果没有测量返回0。它应该这样工作(例如具有类似的值):大型数据集崩溃python脚本

hoursList = [hr1,hr2,hr3,hr4,hr5,hr6] 
measuredList = [hr2,hr3,hr6] 
recordList = [wData1,wData2,wData3] 
finalList = []  

def assignData(i,y):   
    for i < len(leadList):    
     if hoursList[i] == measuredList[y]:     
      finalList.append(recordList[y])     
      i += 1 
      y += 1     
     else:     
      finalList.append(0)     
      i += 1  
     assignData(i,y)  

i = 0 
y = 0  
assignData(i,y) 

其中应该返回

[0,wData1,wData2,0,0,wData3] 

的用于这种情况下得到的finalList(换行符加入帮助可读性)

[0, 'wData1', 'wData2', 0, 0, 'wData3', 'wData3', 
0, 'wData3', 'wData3', 0, 0, 'wData3', 'wData3', 
0, 'wData3', 'wData3', 'wData2', 0, 0, 'wData3', 'wData3', 
0, 'wData3', 'wData3', 0, 0, 'wData3', 'wData3', 
0, 'wData3', 'wData3', 'wData1', 'wData2', 0, 0, 'wData3', 'wData3', 
0, 'wData3', 'wData3', 0, 0, 'wData3', 'wData3', 
0, 'wData3', 'wData3', 'wData2', 0, 0, 'wData3', 'wData3', 
0, 'wData3', 'wData3', 0, 0, 'wData3', 'wData3', 
0, 'wData3', 'wData3'] 

当我尝试运行大型数据列表(约43000个值)的代码,之后崩溃大约7000次迭代。我检查了sys.getrecursionlimit,它是2147483647.任何想法如何获得这项工作?

+0

欢迎来到StackOverflow。请阅读并遵守帮助文档中的发布准则。 [最小,完整,可验证的示例](http://stackoverflow.com/help/mcve)适用于此处。在发布您的MCVE代码并准确描述问题之前,我们无法为您提供有效的帮助。 我们应该能够将发布的代码粘贴到文本文件中,并重现您描述的问题。 尤其是,你还没有给我们leadList' - 更好的是,只需从给定的变量中得出它的长度,所以我们可以运行你的代码。 – Prune

+0

另外,请注意,您的代码不起作用。你有语法错误可以阻止它运行,更不用说你描述的方式了。它不*返回*任何东西;相反,它改变了全球名单作为一个副作用,你没有打扰向我们展示。 – Prune

+0

除此之外,你实际得到的6个元素数据集的输出是什么?我可以在我的例子中看到它,但这应该是*你的问题来描述。 – Prune

回答

2

分析

我推测,len(leadList)是43000数字你给。我会打电话给limit

注意你的循环是如何工作的:在范围内的i每一个值“输入I”到limit,这个处理一个项目,增量i(也许y),和复发。因此,您在i=0的顶级呼叫将产生一个致电assignData(1, 0)(假设失败)的呼叫并等待完成。然后它将回到循环的顶部,与i = 1一起工作,然后继续......最终产生limit递归调用。

该初始呼叫现在将工作范围(1,限制),产卵limit-1调用,其中第一个将产生limit-2调用,等等。每个级别都会产生一个大扇出的另一个级别。

简而言之,你产生的呼叫比我想象的要多得多;随着您增加limit,总增长相当快。

我怀疑你的问题是finalList只是超过了可用内存,因为每个调用都附加了一个元素。

调查

插入基本调试语句转换成代码:

def assignData(i, y): 
    print "ENTER", i, y, finalList 
    for i < len(leadList): 
     ... 

所以,你可以看到通话的进展。

REPAIR

我怀疑你需要这个双重嵌套的递归栈。事实上,我没有看到递归向你购买任何东西。看起来你只需要遍历列表一次,找到实际对应的时间,否则填充0。摆脱呼叫,正确使用for来控制i的值,并根据需要减少代码。

def assignData(): 
    y = 0   
    for i in range(0, len(leadList)):    
     if hoursList[i] == measuredList[y]:     
      finalList.append(recordList[y])     
      y += 1     
     else:     
      finalList.append(0) 

更好的解决方案

如果你需要的是匹配次的记录,可以让这个更直接。建立一个词典来索引时间的测量值。

meas = dict(zip(measuredList, recordList) 

现在,写一个列表理解为任何时候都不要在字典中插入0。

finalList = [meas[time] if time in meas else 0 
       for time in hourslist] 

如果我正确地阅读您的问题,那是您的总体目标。