python - 大数据集使python脚本崩溃

标签 python recursion crash limit grasshopper

我有使用针对Rhino / Grasshopper的GyPython组件的简单脚本。目标是将每小时天气数据(仅记录了一些小时)分配给小时。如果没有测量,则返回0。它应该像这样工作(具有相似值的示例):

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。如何获得这项工作的任何想法?

最佳答案

分析

我收集到len(leadList)是您提供的43000数字。我将其称为limit

请注意您的循环的工作方式:对于“输入i”到i范围内的limit的每个值,此处理一项,递增i(也许是y)并重复出现。因此,您在i=0上进行的顶级调用将生成对assignData(1, 0)的调用(假设失败),并等待该操作完成。然后它将返回循环的顶部,与i = 1一起使用,然后继续...最终连续产生limit递归调用。

现在,该初始调用将适用于范围(1,限制),并生成limit-1调用,其中第一个将生成limit-2调用,依此类推。每个关卡都会产生一个带有大扇出的关卡。

简而言之,您产生的 call 远远超出了我的想象。总数随着limit的增加而增长很快。

我怀疑您的问题是finalList仅仅超出了可用内存,因为这些调用中的每一个都会附加一个元素。

调查

将基本的调试语句插入代码中:

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

这样您就可以查看通话进度。

修复

我怀疑您是否需要此双重嵌套的递归堆栈。实际上,我看不到递归能给您带来任何好处。似乎您只需要遍历列表一次,查找实际对应的时间,否则填写0。摆脱 call ,正确使用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]

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

关于python - 大数据集使python脚本崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45460251/

相关文章:

python - weakref (WeakKeyDictionary) 来框架 (FrameType) 对象

python - Pandas 追加到系列中

c++ - 最长公共(public)递增子序列动态规划

当我调用 EditText 时 Android 应用程序崩溃

Python 3 模块未找到错误 : No module named 'lot'

java - 在 Java 中使用线程和递归计算斐波那契数列

c++ - 对具有按引用传递参数的函数使用递归?

java - 从另一个类导入int变量会使应用程序崩溃

crash - 添加单元测试后,Xcode 8.3.1在启动时崩溃

Python 模块 __builtin__ 没有属性 NoneType