【问题标题】:Reverse a slice of an array in-place [duplicate]就地反转数组的切片[重复]
【发布时间】:2019-04-07 22:09:35
【问题描述】:

就地反转数组的部分的最佳(最快/最pythonic)方法是什么?

例如,

def reverse_loop(l,a,b):
    while a < b:
        l[a],l[b] = l[b],l[a]
        a += 1
        b -= 1

现在

l = list(range(10))
reverse_loop(l,2,6)

l[0, 1, 6, 5, 4, 3, 2, 7, 8, 9],根据需要。

唉,Python中的循环效率很低,所以需要更好的方法,e.g.

def reverse_slice(l,a,b):
    l[a:b+1] = l[b:a-1:-1]

并且reverse_slice(l,2,6)l 恢复为其原始值。

唉,这不适用于边境案件:reverse_slice(l,0,6)l 截断为[7, 8, 9],因为l[a:-1:-1] 应该是l[a::-1]

那么,什么是正确的方式?

【问题讨论】:

  • l[0:6] = l[0:6][::-1] 应该可以工作。另请参阅here
  • @student 在我看来,这个问题是关于 numpy 数组,而这是关于 Python lists
  • @gmds 你的意思是它不适用于 numpy 以外的数组吗?
  • @student 有细微的差别。特别是,切片将以相同的方式工作,但 reversed 方法不会。
  • @gmds 我认为上面链接中的 accepted 答案返回了预期的结果。 a[1:4] = a[1:4][::-1]l[a:b] = l[a:b][::-1] 相同

标签: python arrays python-3.x reverse in-place


【解决方案1】:

这个怎么样?

def reverse_slice(l, a, b):
    l[a:b] = l[a:b][::-1]

l = list(range(10))
reverse_slice(l, 0, 6)  # excludes l[6]
print(l)

输出:

[5, 4, 3, 2, 1, 0, 6, 7, 8, 9]

内置函数reversed的替代方案:

def reverse_func(l, a, b):
    l[a:b] = reversed(l[a:b])

在我的测试中,切片比使用 reversed 快 1.2x-1.5x。

【讨论】:

    【解决方案2】:

    [6::-1]可以写成[6:None:-1]

    def reverse_slice(l,a,b):
        a1 = None if a==0 else a-1
        l[a:b+1] = l[b:a1:-1]
    
    In [164]: y=x.copy(); reverse_slice(y,1,6);y                                    
    Out[164]: [0, 6, 5, 4, 3, 2, 1, 7, 8, 9]
    In [165]: y=x.copy(); reverse_slice(y,0,6);y                                    
    Out[165]: [6, 5, 4, 3, 2, 1, 0, 7, 8, 9]
    

    【讨论】:

    • 这样比重复切片快吗?
    猜你喜欢
    • 1970-01-01
    • 2018-09-23
    • 2017-08-26
    • 2019-10-22
    • 1970-01-01
    • 1970-01-01
    • 2020-03-10
    • 2021-05-22
    • 2018-07-17
    相关资源
    最近更新 更多