简体   繁体   English

索引和切片多维列表

[英]Indexing and slicing a multi-dimensional list

Suppose I have a nested list ( ndlist ) similar to an ND array of arbitrary dimensions (let ndim be the number of dimensions) and a tuple indexes with len(indexes) == ndim .假设我有一个类似于任意维度的 ND 数组(让ndim是维度数)和一个len(indexes) == ndim的元组indexes的嵌套列表( ndlist )。 If ndlist was an ND array I could do the following:如果ndlist是一个 ND 数组,我可以执行以下操作:

ndlist[indexes] = (some object)

What is the equivalent for a list?列表的等价物是什么? Note that ndim is arbitrary so I can't hardcode it like this:请注意, ndim是任意的,所以我不能像这样对其进行硬编码:

ndlist[indexes[0]][indexes[1]]... = (some object)

Here's an example for ndim == 3 :这是ndim == 3的示例:

ndlist = [[[10, 10], [10, 10]],[[10, 10], [10, 10]]] % 3-D (2x2x2) list with all elements equal to 10 ndlist = [[[10, 10], [10, 10]],[[10, 10], [10, 10]]] % 3-D (2x2x2) 列表,所有元素等于 10

When I know ndim beforehand I can edit the (0,0,0) element of ndlist like this:当我事先知道ndim 时,我可以像这样编辑ndlist的 (0,0,0) 元素:

ndlist[0][0][0] = 11 %changing from 10 to 11 requires 3 [0]s in sequence ndlist[0][0][0] = 11 % 从 10 到 11 的变化需要 3 [0] 秒

Now suppose ndims == 4 (4-dimensional list).现在假设 ndims == 4(4 维列表)。 Editing the the (0,0,0,0) element of ndlist would require something like this:编辑 ndlist 的 (0,0,0,0) 元素需要这样的东西:

ndlist[0][0][0][0] = 11 %change to 11 requires 4 [0]s in sequence ndlist[0][0][0][0] = 11 % 更改为 11 需要 4 [0] 秒

And for arbitrary ndims:对于任意 ndim:

ndlist[0][0][0]...[0] ndlist[0][0][0]...[0] = 11 %change to 11 requires ndim [0]s in sequence = 11 %change 到 11 需要 ndim [0]s 顺序

As you see, I can't index the list that way for the general case where ndim is not known in advance, as it requires to type as many [0] as ndim.如您所见,对于预先不知道 ndim 的一般情况,我无法以这种方式索引列表,因为它需要键入与 ndim 一样多的 [0]。

If instead of the list I had an array like this:如果我有一个这样的数组而不是列表:

ndarray = np.array(ndlist) ndarray = np.array(ndlist)

Accessing the (0, 0, 0, ... ,0) would not be an issue since I can using a tuple to index all dimensions simultaneously like that:访问 (0, 0, 0, ... ,0) 不会成为问题,因为我可以使用元组同时索引所有维度,如下所示:

% 3d case % 3d 案例

indexes = (0,0,0)索引 = (0,0,0)

ndarray[indexes] ndarray[索引]

% 4d case % 4d 案例

indexes = (0,0,0,0)索引 = (0,0,0,0)

ndarray[indexes] ndarray[索引]

% nd case % 案例

indexes = (0, 0, 0, ... ,0) % I can generate this with code索引 = (0, 0, 0, ... ,0) % 我可以用代码生成这个

ndarray[indexes] = 11 ndarray[索引] = 11

Is there a way to index a list with a single tuple like that?有没有办法用这样的单个元组索引列表? Even better, can the tuple hold slices instead of indexes?更好的是,元组可以保存切片而不是索引吗? For instance arrays also allow this:例如数组也允许这样做:

ndarray[ 0:2 , 0, 0] = np.array([0, 0]) ndarray[ 0:2 , 0, 0] = np.array([0, 0])


The only solution have found to my problem is to use recursion to index one dimension at a time.我的问题找到的唯一解决方案是使用递归一次索引一个维度。 Is there a better solution?有更好的解决方案吗? Thanks!谢谢!

Now I understood the problem.现在我明白了这个问题。 If you are willing to have a function donig that for you it will be easy.如果您愿意拥有一个对您来说很容易的函数 donig。 Otherwise you'll need to create your own list type.否则,您需要创建自己的列表类型。

Function功能

You will need a function which takes a list and n (unknown) number of elements.您将需要一个函数,它接受一个列表和n (未知)个元素。 The n means you will need *argv n意味着您将需要*argv

The function will get the list and get the i th element in n ( argv ).该函数将获取列表并获取n ( argv ) 中的第i个元素。

def get_element(the_list, *argv):
    sub_list = the_list.copy()
    for i in argv:
        sub_list = sub_list[i]

    return sub_list

Note: The function copies the original list to make sure it's not changed.注意:该函数复制原始list以确保它没有被更改。

Note: You will need to handle the index out of range error too.注意:您还需要处理index out of range错误。 Right now it will raise an error of TypeError: 'blabla' object is not subscriptable .现在它会引发TypeError: 'blabla' object is not subscriptable

Your own list type您自己的列表类型

Here you will create a class with any name (let's sat TypedList ) which inherits from list and override the __getitem__ method.在这里,您将创建一个具有任何名称的类(让我们使用TypedList ),它继承自list并覆盖__getitem__方法。

class TypedList(list):
    def __getitem__(self, keys):
        sub_list = self.copy()
        for i in keys:
            sub_list = sub_list[i]

        return sub_list


if __name__ == '__main__':
    ndlist = [[[1, 2], [3, 4]], [[5, 6], [7, 8]]]
    lst = TypedList(ndlist)
    print(lst[1, 1, 0, 2])

Here you will need handle the index out of range error too.在这里,您还需要处理index out of range错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM