通过python中的索引元组访问多维列表值

时间:2015-08-19 15:09:28

标签: python multidimensional-array

我有一个复杂的多维可测对象(比如列表)。我想编写函数来访问由元组索引表示的元素的值。维度的数量本身是可变的。如果元素不存在,它也应该返回None

l = [[[1, 2],
      [3, 4]],
     [[5, 6],
      [7, 8]]]
access(l, (0, 0, 0)) # prints 1
access(l, (0, 1, 1)) # prints 4
access(l, (1, 1)) # prints [7, 8]
access(l, (0, 1, 2)) # prints None
access(l, (0, 0, 0, 0)) # prints None

我如何实现这一目标?

3 个答案:

答案 0 :(得分:2)

雅罗斯拉夫答案的另一种方法,在索引列表之前,你要求宽恕而不是许可:

def access(obj, indexes):
    try:
        return reduce(list.__getitem__, indexes, obj)
    except Exception:
        return None

这不是万无一失的;它会假设access将按预期使用,如果有人决定尝试None,您不介意回复access(1, 1)

答案 1 :(得分:2)

正如切普纳所暗示的那样,这并不是一件难事,但要小心一点。仅当异常为None时才返回IndexError,并且尝试的内容更具体。像

这样的东西
def access(obj, indexes):
    a = obj
    for i in indexes:
       try: 
           a = a[i]
       except IndexError:
           return None
       # except TypeError:
           # when you try to index deeper than the object supports

    # a  is not constrained to be a scalar, it may still be dimensional
    # if insufficient indexes were passed.
    return a  
如果在某些级别你有一个dict而不是列表,这将是有效的。即

x = access(obj, (3, 'default', 'range', 1))

将适用于适当的对象,如果一个或两个级别不是dict或者没有密钥,则会抛出异常。我使用了非常类似的内容来访问JSON.load结果。您可能还希望在None上返回KeyError,这是与IndexError相当的字典。

您可以添加isinstance(a, list)hasattr(a, '__iter__')等测试,以便更加确定您正在为预期目标建立索引。

答案 2 :(得分:1)

您可以使用reduce()执行此操作:

def access(obj, indexes):
    return reduce(lambda subobj, index: subobj[index] if isinstance(subobj, list) and index < len(subobj) else None, indexes, obj)

或者正如@chepner指出的那样,您可以使用def使其更具可读性:

def access(obj, indexes):
    def _get_item(subobj, index): 
        if isinstance(subobj, list) and index < len(subobj):
            return subobj[index]
        return None

    return reduce(_get_item, indexes, obj)