动态列表切片

0 投票
2 回答
831 浏览
提问于 2025-04-15 13:45

大家好,代码骑士们,

我遇到了一个棘手的问题,找不到简单的解决办法。人类历史告诉我们,所有事情都有简单的解决方案(除了买礼物这件事)。

问题是这样的:

我需要一个算法,它可以处理多维列表和一个过滤字典,然后根据这些过滤条件返回相应的列表。

举个例子:

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)]

撰写回答