Python反向跨步切片
我的问题的一个具体例子是,“在这个例子中我怎样才能得到‘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'
看起来很奇怪,我可以写 foo[4:0:-1]、foo[5:1:-1] 等并得到我所期望的结果,但没有办法写切片以便我得到 '3210 '。
一种临时方法是 foo[0:4][::-1],但这会在进程中创建两个字符串对象。我将执行此操作数十亿次,因此每个字符串操作都很昂贵。
我一定错过了一些愚蠢而简单的事情。感谢您的帮助!
A specific example of my question is, "How can I get '3210' in this example?"
>>> 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'
It seems strange that I can write foo[4:0:-1], foo[5:1:-1], etc. and get what I would expect, but there's no way to write the slice so that I get '3210'.
A makeshift way of doing this would be foo[0:4][::-1], but this creates two string objects in the process. I will be performing this operation literally billions of times, so every string operation is expensive.
I must be missing something silly and easy. Thanks for your help!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
给定:
所需的字符串
3210
是从索引第 3 个字符到第 0 个字符:以下是两个通用解决方案:
获取正向切片然后反转它:
<前><代码>>>> foo[stop_idx:start_idx+1][::-1]
‘3210’
根据这个答案,使用负步长并在第一个元素之前停止 1 个元素(加上停止偏移量):
<前><代码>>>> foo[start_idx:stop_idx-len(foo)-1:-1]
‘3210’
>>>>> a[start_idx:stop_idx-len(a)-1:-1]
[2, 1]
比较执行时间,第一个版本更快:
Given:
The desired string
3210
is from index 3rd to the 0-th characters:Here are two generic solutions:
Take the forward slice then reverse it:
Based on this answer, use a negative step and stop 1 element before the first element (plus the stop offset):
Comparing execution times, the first version is faster:
除了上述解决方案之外,您还可以执行以下操作:
我猜如果 foo 将改变长度,这可能不是最好的解决方案,但如果长度是静态的,它会起作用。
In addition to the above solutions, you can do something like:
I guess if foo is going to be changing lengths, this may not be the best solution, but if the length is static it would work.
如果您正在寻找比扩展切片符号更易于理解的东西:
If you're looking for something a little more human-readable than extended slice notation:
阅读“技术文档”(此处)后 - 特别是这句话:
我决定尝试一下,它起作用了:
所以我认为以编程方式确定“终点”的最佳答案是提供一个命名良好的辅助函数,该函数清楚地表明其参数始终被视为正偏移量,也许
special_slice()
我认为这种“特殊”情况的清晰度非常重要,因为许多常见和重要的用例都取决于负偏移量的默认行为(即向其添加长度)。就我个人而言,我经常使用“-1”端点来表示:在最后一个元素之前停止。
因此,根据您的评论:
我可能会做出以下操作:
然后为所需的每个切片调用它:
上面的内容可以轻松地循环遍历“i”的值
After reading the "technical documentation" (here) - specifically the sentence:
I decided to try this, and it worked:
So I think the best answer to programmatically determine the "end point" would be to provide a well named helper function that makes it clear that its arguments are always treated like positive offsets, maybe
special_slice()
I think the clarity of this 'special' case is extremely important since lots of common and significant use cases depend on the default behavior of negative offsets (i.e. adding the length to them). Personally I frequently use a '-1' end point to mean: stop just before last element.
So, based on your comment:
I might make the following:
And then call it for each slice required:
The above could easily go in a loop over values of 'i'
您可以使用
s[::-1]
反转整个字符串。但如果你想反转每个固定长度的子串,你可以先提取子串,然后反转整个子串。例如,假设我们需要检查字符串foo
中每个长度为 3 的子串是否是回文,我们可以这样做:如果你想检查一个子串是否是回文,如下所示
:将无法处理
i
为0
的情况,因为您实际上是将foo[0:3]
与foo 进行比较[2:-1:-1]
,相当于foo[2:n-1:-1]
,后者是一个空字符串。第一个解决方案的唯一缺点是它使用了更多的内存,但这没什么大不了的。
You can use
s[::-1]
to reverse the entire string. But if you want to reverse each substring with some fixed length, you can first extract the substring and then reverse the entire substring. For example, let's assume we need to check whether each substring with length 3 of stringfoo
is a palindrome, we can do it like this:If you want to check if a substring is palindrome like this:
you will not be able to handle the case of
i
being0
, since you are actually comparingfoo[0:3]
withfoo[2:-1:-1]
, which is equivalent tofoo[2:n-1:-1]
, which in turn is an empty string.The only drawback of the first solution is that it uses a little more memory but it's no big deal.
省略切片符号中的结束索引:
如果您必须多次执行此操作,请创建一个可以反复使用的切片对象
Omit the end index in your slice notation:
If you have to do this many times, create a slice object that you can use over and over
只需排除结束范围索引...
具有讽刺意味的是,关于我认为您没有尝试的唯一选项。
Simply exclude the end range index...
Ironically, about the only option I think you didn't try.