Python - 逗号分隔的切片不起作用

Python - comma separated slices not working

提问人: 提问时间:8/15/2021 更新时间:8/15/2021 访问量:214

问:

我见过很多人在对多维列表进行切片时使用逗号。例如:

a = [[0, 1, 2, 3, 4], [5, 6, 7, 8, 9]]
print(a[0:1, 2:4])

但出于某种原因,它对我不起作用。它引发了一个异常:

TypeError: list indices must be integers or slices, not tuple

我该如何解决???

Python 多维数组 切片

评论

0赞 balderman 8/15/2021
在这种情况下,您的预期输出是多少?
0赞 8/15/2021
@balderman 那将是 [2, 3]
0赞 balderman 8/15/2021
尝试print(a[0][2:4])
0赞 8/15/2021
@balderman 但是说尺寸是任意的,我不知道我必须执行多少个切片。
0赞 Copperfield 8/15/2021
常规的 Python 列表不支持这种高级类型的切片,您要么需要按@balderman所示的部分进行切片,要么创建自己的支持它的类或列表子类,要么只是使用支持它的库,例如 numpy

答:

0赞 pu239 8/15/2021 #1

当您使用 numpy 数组而不是 python 的内置列表时,这是可能的。
例:

a = [[0, 1, 2, 3, 4], [5, 6, 7, 8, 9]]
print(a[0,1]) # returns an error
b = np.array(a)
print(b[0,1]) # returns 1

同样,您也可以使用切片。

评论

0赞 tdelaney 8/15/2021
其他包也允许这种类型的索引。
0赞 pu239 8/15/2021
我想断言,使用 python 的内置列表是不可能的
1赞 tdelaney 8/15/2021
是的,令人担忧的是它仅在 numpy 中可用的措辞。
0赞 de1 8/15/2021 #2

在这种情况下,实际上只是一个嵌套列表,而不是一个真正的矩阵。 将其转换为数组后,访问这些切片将开始工作。anumpy

例如:

import numpy as np

a = np.asarray([[0, 1, 2, 3, 4], [5, 6, 7, 8, 9]])
print(a[0:1, 2:4])
0赞 tdelaney 8/15/2021 #3

对象自行决定如何为它们编制索引。当 python 看到它时,首先为分隔的值创建切片对象,然后将它们组合成一个元组:.该元组将传递给对象的 : 。将该元组传递给 and its lost - 它无法识别这种类型的索引。把它放在一个 pandas 数据帧中,并使用其基于“iloc”索引的索引,它就可以工作了。a[0:1, 2:4]:(slice(0, 1, None), slice(2, 4, None))__getitem__a[(slice(0, 1, None), slice(2, 4, None))]list.__getitem__

>>> a = [[0, 1, 2, 3, 4], [5, 6, 7, 8, 9]]
>>> a[0:1, 2:4]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: list indices must be integers or slices, not tuple
>>> import pandas as pd
>>> df = pd.DataFrame(a)
>>> df.iloc[0:1, 2:4]
   2  3
0  2  3

还有其他类似的软件包,它突破了索引的含义。所以要回答你的问题,这取决于你说的是什么类型的物体。不同的对象可以自由地以不同的方式解释切片。pandas

评论

0赞 8/15/2021
那好吧。我会做一个班级来做这件事......MultiDimSlicer
2赞 tdelaney 8/15/2021
@RudraPatel - 当然可行。你也可以写一个函数来做到这一点。当你实现你的类时,特别是如果它继承自内置类,它可能需要比 single-purose 函数更多的代码。def slicer(my_list, *slices)list
0赞 user16519472 8/15/2021 #4

我为这个切片做了一个类,就像你回答的那样。MultiDimSlicer

class MultiDimSlicer:
    def __init__(self, data):
        self.data = data
    def __iter__(self):
        return iter(self.data)
    def __getitem__(self, keys):
        return eval("self.data" + self.__slicestr(keys))
    def __setitem__(self, keys, value):
        exec("self.data" + self.__slicestr(keys) + " = " + str(value))
    def __slicestr(self, keys):
        slice_str = ""
        if isinstance(keys[0], itertypes):
            good_keys = keys[0]
        else:
            good_keys = keys
        for key in good_keys:
            slice_str += "[" + str(key) + "]"
        return slice_str
    reuse = __init__