【问题标题】:Use a variable to describe an index range/slice for array / list indexing使用变量来描述数组/列表索引的索引范围/切片
【发布时间】:2020-04-01 18:27:47
【问题描述】:

我想使用一个名称来引用数组/列表索引的索引范围。 另外,我希望能够对其进行算术运算。 比如我想做

myrange = 3:10
myrange2 = myrange + 5
arr2[myrange2] = arr1[myrange]  # This being equivalent to arr2[8:15] = arr1[3:10] 
myrange3 = myrange * 2 + 5
arr2[myrange3] = arr1[myrange]  # This being equivalent to arr2[11:25] = arr1[3:10] 

python 列表和 numpy 数组可以做到这一点吗?

【问题讨论】:

  • 看起来很难,因为 slice 不是子类 stackoverflow.com/a/39971377/7207392。也使用 dunders __int____index__ 似乎不起作用。
  • 'm:n' 切片表示法仅适用于索引表达式。也就是说,它是一个 Python 语法特性。解释器将其转换为slilce 对象,并将其传递给__getitem__ 方法。切片对象本身非常简单,只有几个属性。 np.s_np.r_ 是特殊的 numpy 类实例,有助于生成和扩展切片。
  • @hpaulj - 我会尝试消化你的评论。同时,你会说我的问题的答案是Yes还是No? (我无法从评论中弄清楚这一点)。
  • 不,您不能让 Python 解释器评估 myrange = 3:10。这是invalid syntax 错误。
  • @hpaulj - 请查看答案中的方法......他们似乎表明这是可能的(通过不严格使用符号3:10,但能够命名一个切片).. .

标签: python numpy indexing slice


【解决方案1】:

您可以简单地使用slice()

myrange = slice(3, 10)
myrange2 = slice(3 + 5, 10 + 5)
arr2[myrange2] = arr1[myrange]

这可以很容易地变成一个函数:

def add_to_slice(slice_, offset):
    return slice(slice_.start + offset, slice_.stop + offset)


myrange = slice(3, 10)
myrange2 = add_to_slice(myrange, 5)
arr2[myrange2] = arr1[myrange]

如果您想使用+,则需要修补slice 类(因为slice 不是可接受的基类)以包含__add__ 方法,即:

class Slice(slice):
    pass

TypeError: type 'slice' 不是可接受的基本类型


编辑

“可能足够接近”的方法是将slice 包裹在另一个类周围,比如Slice,并且可以选择让访问内部slice 变得容易,例如:

class Slice(object):
    def __init__(self, *args):
        self.slice_ = slice(*args)

    def __call__(self):
        return self.slice_

    def __add__(self, offset):
        return Slice(self.slice_.start + offset, self.slice_.stop + offset, self.slice_.step)


myrange = Slice(2, 5)
myrange2 = myrange + 3

mylist = list(range(100))
print(mylist[myrange()])
print(mylist[myrange2()])

(您可能需要优化生产代码以处理slice 的属性可能是None)。

【讨论】:

  • 非常有趣的方法。我会试试这个。我的意思是能够进行其他算术运算,甚至是复合运算(例如,slice * 2 + 4)。使用这种方法,在我看来也很简单,通过定义__multiply__ 等。你会这么认为吗?
  • @sancho.sReinstateMonica 是的,您可以查看 operator 模块以查看要实现的内容(例如,* 运算符是 __mul__ 等)。请注意,您还可以使用 colon 语法在构造函数中接受 str,这将允许您编写 Slice('1:10') 来代替 Slice(1, 10),尽管这对于处理用户输入可能很有用而不是简化代码中的语法。
【解决方案2】:

您可以使用slice

a = slice(1,3)
'hello'[a] -> ell

您可以使用 a.start/a.stop/a.step 访问属性。这些属性是只读的,但您可以根据算术要求从它们创建一个新切片

【讨论】:

    猜你喜欢
    • 2021-08-25
    • 2017-05-17
    • 2015-02-23
    • 2021-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-02
    • 2013-11-30
    相关资源
    最近更新 更多