我的问题的一个具体例子是,“我在这个例子中如何获得'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],但这会在进程中创建两个字符串对象。我将在数十亿次执行此操作,因此每个字符串操作都很昂贵。
我必须遗漏一些愚蠢而容易的东西。谢谢你的帮助!
答案 0 :(得分:37)
只需排除结束范围索引......
>>> foo[3::-1]
'3210'
讽刺的是,关于我认为你没有尝试的唯一选择。
答案 1 :(得分:8)
如果你正在寻找比扩展切片符号更人性化的东西:
>>> foo = '0123456'
>>> ''.join(reversed(foo[0:4]))
'3210'
答案 2 :(得分:6)
在切片表示法中省略结束索引:
>>> foo = '0123456'
>>> foo[3::-1]
'3210'
如果必须多次这样做,请创建一个可以反复使用的切片对象
>>> i = slice(3,None,-1)
>>> foo[i]
'3210'
答案 3 :(得分:3)
您可以使用s[::-1]
来反转整个字符串。但是,如果要以固定长度反转每个子字符串,可以先提取子字符串,然后反转整个子字符串。例如,假设我们需要检查字符串foo
的长度为3的每个子字符串是否为回文,我们可以这样做:
>>> foo = '0102030'
>>> for i in range(len(foo)-3):
... if foo[i:i+3] == foo[i:i+3][::-1]:
... print(foo[i:i+3], 'is a palindrome')
... else:
... print(foo[i:i+3], 'is not a palindrome')
...
010 is a palindrome
102 is not a palindrome
020 is a palindrome
203 is not a palindrome
030 is a palindrome
如果你想检查子串是否是这样的回文:
if foo[i:i+3] == foo[i+2:i-1:-1]:
...
您将无法处理i
0
的情况,因为您实际上是将foo[0:3]
与foo[2:-1:-1]
进行比较,这相当于foo[2:n-1:-1]
},而这又是一个空字符串。
第一个解决方案的唯一缺点是它使用了更多的内存,但这没什么大不了的。
答案 4 :(得分:3)
阅读“技术文档”(here)后 - 特别是句子:
如果任一边界为负数,则将序列的长度添加到其中。
我决定尝试这个,它有效:
>>> foo = '0123456'
>>> foo[3:-1-len(foo):-1]
'3210'
>>>
所以我认为以编程方式确定“终点”的最佳答案是提供一个命名良好的辅助函数,该函数清楚地表明其参数总是被视为正偏移,可能是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]
然后为每个切片调用它:
foo_part = slice_by_len(foo, i, 4, -1)
以上内容很容易绕过'i'
的值答案 5 :(得分:1)
除上述解决方案外,您还可以执行以下操作:
foo = '0123456'
foo[-4::-1]
我想如果foo将会改变长度,这可能不是最好的解决方案,但如果长度是静态的,那就可以了。
答案 6 :(得分:0)
假设:
>>> foo = '0123456'
所需的字符串3210
是从索引3到第0个字符:
>>> stop_idx=0
>>> start_idx=3
以下是两种通用解决方案:
取向前切片然后反转它:
>>> foo[stop_idx:start_idx+1][::-1]
'3210'
基于this answer,使用否定步骤并在第一个元素之前停止1个元素(加上停止偏移量):
>>> foo[start_idx:stop_idx-len(foo)-1:-1]
'3210'
>>> a[start_idx:stop_idx-len(a)-1:-1]
[2, 1]
比较执行时间,第一个版本更快:
>>> timeit.timeit('foo[stop_idx:start_idx+1][::-1]', setup='foo="012345"; stop_idx=0; start_idx=3', number=10_000_000)
1.7157553750148509
>>> timeit.timeit('foo[start_idx:stop_idx-len(foo)-1:-1]', setup='foo="012345"; stop_idx=0; start_idx=3', number=10_000_000)
1.9317215870250948
答案 7 :(得分:-2)
s="this is my world"
pattern=re.findall(r'\S+',s)
a=[]
for i in range(len(pattern)):
a.append((pattern[i][::-1]))
print (a)
print (" ".join(a))