动态列表切片
大家好,代码骑士们,
我遇到了一个棘手的问题,找不到简单的解决办法。人类历史告诉我们,所有事情都有简单的解决方案(除了买礼物这件事)。
问题是这样的:
我需要一个算法,它可以处理多维列表和一个过滤字典,然后根据这些过滤条件返回相应的列表。
举个例子:
Bathymetry ('x', 'y')=(182, 149) #notation for (dimensions)=(size)
Chl ('time', 'z', 'y', 'x')=(4, 31, 149, 182)
filters {'x':(0,20), 'y':(3), 'z':(1,2), time:()} #no filter stands for all values
这个例子会返回:
readFrom.variables['Bathymetry'][0:21, 3]
readFrom.variables['Chl'][:, 1:3, 3, 0:21]
我在想用一个循环来处理这些维度,从过滤列表中读取过滤条件,但我就是搞不清楚怎么把这些属性传递给切片操作。
任何帮助都非常感谢。
2 个回答
3
我不太确定我理解了你的问题。不过我觉得你可能在找的是 slice
对象:
首先,不要用一个空的元组,改用 None 这样可以包含所有的时间值。
filters= {'x':(0,20), 'y':(3), 'z':(1,2), 'time':None}
接着,像这样构建一个切片字典:
d = dict(
(k, slice(*v) if isinstance(v, tuple) else slice(v))
for k, v in filters.iteritems()
)
这是输出结果:
{
'y': slice(None, 3, None),
'x': slice(0, 20, None),
'z': slice(1, 2, None),
'time': slice(None, None, None)
}
然后你可以用这些切片对象从列表中提取出你想要的范围。
2
像下面这样的代码应该可以正常工作:
def doit(nam, filters):
alldims = []
for dimname in getDimNames(nam):
filt = filters.get(dimname, ())
howmany = len(filt)
if howmany == 0:
sliciflt = slice()
elif howmany == 1:
sliciflt = filt[0]
elif howmany in (2, 3):
sliciflt = slice(*filt)
else:
raise RuntimeError("%d items in slice for dim %r (%r)!"
% (howmany, dimname, nam))
alldims.append(sliciflt)
return readFrom.variables[nam][tuple(alldims)]