我有使用GyPython组件的简单脚本用于Rhino / Grasshopper。目标是将每小时的天气数据(仅记录几小时)分配到几小时。如果没有测量值则返回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.任何想法如何让这项工作?
答案 0 :(得分:2)
<强>分析强>
我认为len(leadList)
是你提供的43000个数字。我将此称为limit
。
注意你的循环是如何工作的:对于&#34;输入i&#34;范围内的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]
如果我正确地阅读了您的问题,那就是您的总体目标。