Python :反向迭代时包括最后一个元素(其中 i=0)
Python : include last element (where i=0) when iterating in reverse
我有一个字符串 string = 'cbAfeDihGlkJonMrqPutS'
,我想遍历它以产生 'AbcDefGhiJklMnoPqrStu'
.
我正在使用以下 for 循环来实现 'DefGhiJklMnoPqrStu
,但是缺少预期的 Abc
。
for i in (range(0, len(string), 3)):
print(string[i+2 : i-1 : -1], end='')
这似乎是一个问题,因为我的结束元素 : i-1 :
中的 -1
,但是我想知道为什么反向迭代(步长为 -1
)并使用:i-1:
捕获第一个元素(其中 i=0)与向前迭代并使用 : i+1 :
捕获最后一个元素的工作方式不同。
我能够通过
实现我想要的解决方案
for i in (range(0, len(string), 3)):
print(string[i:i+3:1][::-1], end='')
但是向前迭代和向后打印似乎是一种笨拙的方法。必须添加 [::-1]
似乎是一个多余的步骤,如果 [i+2 : i-1 : -1]
有效。
除了 [i:i+3:1][::-1]
之外,还有更简洁的方法吗?
最优雅的方法可能是使用 ''.join()
和理解将您已经想出的循环压缩成一行。
string = 'cbAfeDihGlkJonMrqPutS'
print(''.join(string[i:i+3][::-1] for i in range(0, len(string), 3)))
# AbcDefGhiJklMnoPqrStu
您认为您可以像 string[i+2:i-1:-1]
这样的操作去掉多余的 [::-1]
,但正如您所观察到的,这会截断字符串中的第一个字符.这是切片语法的一个怪癖,切片的 end
边界是 exclusive 而不是 inclusive,但同时索引 -1
指的是结尾的字符串而不是 'the character before the beginning'(这将超出范围,比如说 Java,但我们不会有这个问题)。据我所知,没有办法解决这个问题。
您也可以尝试使用 reversed()
而不是 [::-1]
,但我不认为这会使它变得更简单或更快:
print(''.join(c for i in range(0, len(string), 3) for c in reversed(string[i:i+3])))
编辑:正如@don't talk just code pointed out in a comment,实际上是可以规避这个问题,因为将None
作为第二个切片的参数将使切片继续到列表的任何一端是合适的(直到这个评论我不知道这一点)。考虑到这一点,我们确实可以只用一片来完成这件事:
print(''.join(string[i+2:i-1 if i else None:-1] for i in range(0, len(string), 3)))
# AbcDefGhiJklMnoPqrStu
它有点不雅,但它似乎有效,并且比上面的更符合您的要求。
我有一个字符串 string = 'cbAfeDihGlkJonMrqPutS'
,我想遍历它以产生 'AbcDefGhiJklMnoPqrStu'
.
我正在使用以下 for 循环来实现 'DefGhiJklMnoPqrStu
,但是缺少预期的 Abc
。
for i in (range(0, len(string), 3)):
print(string[i+2 : i-1 : -1], end='')
这似乎是一个问题,因为我的结束元素 : i-1 :
中的 -1
,但是我想知道为什么反向迭代(步长为 -1
)并使用:i-1:
捕获第一个元素(其中 i=0)与向前迭代并使用 : i+1 :
捕获最后一个元素的工作方式不同。
我能够通过
实现我想要的解决方案for i in (range(0, len(string), 3)):
print(string[i:i+3:1][::-1], end='')
但是向前迭代和向后打印似乎是一种笨拙的方法。必须添加 [::-1]
似乎是一个多余的步骤,如果 [i+2 : i-1 : -1]
有效。
除了 [i:i+3:1][::-1]
之外,还有更简洁的方法吗?
最优雅的方法可能是使用 ''.join()
和理解将您已经想出的循环压缩成一行。
string = 'cbAfeDihGlkJonMrqPutS'
print(''.join(string[i:i+3][::-1] for i in range(0, len(string), 3)))
# AbcDefGhiJklMnoPqrStu
您认为您可以像 string[i+2:i-1:-1]
这样的操作去掉多余的 [::-1]
,但正如您所观察到的,这会截断字符串中的第一个字符.这是切片语法的一个怪癖,切片的 end
边界是 exclusive 而不是 inclusive,但同时索引 -1
指的是结尾的字符串而不是 'the character before the beginning'(这将超出范围,比如说 Java,但我们不会有这个问题)。据我所知,没有办法解决这个问题。
您也可以尝试使用 reversed()
而不是 [::-1]
,但我不认为这会使它变得更简单或更快:
print(''.join(c for i in range(0, len(string), 3) for c in reversed(string[i:i+3])))
编辑:正如@don't talk just code pointed out in a comment,实际上是可以规避这个问题,因为将None
作为第二个切片的参数将使切片继续到列表的任何一端是合适的(直到这个评论我不知道这一点)。考虑到这一点,我们确实可以只用一片来完成这件事:
print(''.join(string[i+2:i-1 if i else None:-1] for i in range(0, len(string), 3)))
# AbcDefGhiJklMnoPqrStu
它有点不雅,但它似乎有效,并且比上面的更符合您的要求。