Python反向跨越切片

ebl*_*ume 30 python string slice

我的问题的一个具体例子是,"在这个例子中我如何得到'3210'?"


>>> foo = '0123456'
>>> foo[0:4]
'0123'
>>> foo[::-1]
'6543210'
>>> foo[4:0:-1] # I was shooting for '3210' but made a fencepost error, that's fine, but...
'4321'
>>> foo[3:-1:-1] # How can I get '3210'?
''
>>> foo[3:0:-1]
'321'
Run Code Online (Sandbox Code Playgroud)

看起来很奇怪,我可以写foo [4:0:-1],foo [5:1:-1]等等,并得到我所期望的,但是没有办法写切片让我得到'3210 ".

这样做的临时方法是foo [0:4] [:: - 1],但这会在进程中创建两个字符串对象.我将在数十亿次执行此操作,因此每个字符串操作都很昂贵.

我一定要错过愚蠢和容易的事情.谢谢你的帮助!

And*_*ite 38

只需排除结束范围索引......

>>> foo[3::-1]
'3210'
Run Code Online (Sandbox Code Playgroud)

具有讽刺意味的是,关于我认为你没有尝试的唯一选择.

  • 或者传递"无". (4认同)
  • 问题是这个切片操作正在一个算法中使用,其工作方式如下:foo [i:i-4:-1],并以高'i'开始并向下走.我不能只删除'我'.我想我可以使用边缘情况并说"如果i-4 <0,则使用另一个切片". (4认同)
  • 好吧,公平地说,你没有在你的问题中包含那个条件,即便如此,你也可以将这个"笨重"的逻辑包装在一个函数中并完成它. (2认同)
  • 如果你想使用负索引,你必须计算负步的数量,比如 `s[len(s)-1 : - (len(s)+1) : -1]` (2认同)

Aar*_*our 8

如果你正在寻找比扩展切片符号更人性化的东西:

>>> foo = '0123456'
>>> ''.join(reversed(foo[0:4]))
'3210'
Run Code Online (Sandbox Code Playgroud)

  • 谢谢,但不,这会创建*三个*内存对象.加入和反转非常快,但我认为可以安全地假设扩展切片表示法会更快. (4认同)
  • 我通常假设如果你在python中编写,效率并不是最重要的.唯一可能重要的是可读性,因此我对此进行了优化.扩展切片表示法,特别是具有负步长值的切片表示法,非常不透明. (2认同)

Pau*_*McG 8

在切片表示法中省略结束索引:

>>> foo = '0123456'
>>> foo[3::-1]
'3210'
Run Code Online (Sandbox Code Playgroud)

如果必须多次执行此操作,请创建一个可以反复使用的切片对象

>>> i = slice(3,None,-1)
>>> foo[i]
'3210'
Run Code Online (Sandbox Code Playgroud)

  • 你可以去foo [3:没有,如果我<0,否则i:-1]. (8认同)
  • 哇 !我不知道 slice() 。+1 (2认同)

Cra*_*Neb 5

阅读“技术文档”(此处)后 - 特别是这句话:

如果任一边界为负,则将序列的长度添加到其中。

我决定试试这个,它奏效了:

>>> foo = '0123456'
>>> foo[3:-1-len(foo):-1]
'3210'
>>>
Run Code Online (Sandbox Code Playgroud)

所以我认为以编程方式确定“终点”的最佳答案是提供一个命名良好的辅助函数,它清楚地表明它的参数总是被视为正偏移量,也许 special_slice()

我认为这种“特殊”情况的清晰度非常重要,因为许多常见和重要的用例取决于负偏移的默认行为(即向它们添加长度)。我个人经常使用“-1”结束点来表示:在最后一个元素之前停止。

因此,根据您的评论:

... 算法的工作原理如下: foo[i:i-4:-1],并以高位 'i' 开始并向下走。

我可能会做以下事情:

def slice_by_len(data, start, length, step=1):
    end = start + length if step > 0 else start - length
    if end < 0:
        # Fix the negative offset to get what we really want
        end -= len(data)
    return data[start:end:step]
Run Code Online (Sandbox Code Playgroud)

然后为每个所需的切片调用它:

foo_part = slice_by_len(foo, i, 4, -1)
Run Code Online (Sandbox Code Playgroud)

以上可以很容易地循环遍历 'i' 的值

  • 试图用 Python 实现这一点是很丑陋的!我在[此处]引用了您的答案(/sf/answers/3486837301/)。 (2认同)