Home > Blockchain >  Python : include last element (where i=0) when iterating in reverse
Python : include last element (where i=0) when iterating in reverse

Time:10-23

I have a string string = 'cbAfeDihGlkJonMrqPutS' and I would like to iterate through it in order to yield 'AbcDefGhiJklMnoPqrStu'.

I am using the following for loop to achieve 'DefGhiJklMnoPqrStu, however the expected Abc is missing.

for i in (range(0, len(string), 3)):
    print(string[i 2 : i-1 : -1], end='')

This seems to be a problem due the -1 in my ending element : i-1 :, however I am wondering why iterating in reverse (with a step size of -1) and using :i-1: to capture the first element (where i=0) does not work similarly to iterating forwards and using : i 1 : for capturing the last element.

I am able to achieve my desired solution with

for i in (range(0, len(string), 3)):
    print(string[i:i 3:1][::-1], end='')

but iterating forwards and printing backwards seems like a clunky way to do it. Having to add [::-1] seems like an otherwise superfluous step, were [i 2 : i-1 : -1] to have worked.

Is there are cleaner way to do this, other than [i:i 3:1][::-1] ?

CodePudding user response:

The most elegant way to do it is probably to use ''.join() and a comprehension to compress the loop you already came up with into a single line.

string = 'cbAfeDihGlkJonMrqPutS'
print(''.join(string[i:i 3][::-1] for i in range(0, len(string), 3)))
# AbcDefGhiJklMnoPqrStu

You'd think you'd be able to get rid of the extra [::-1] by doing like string[i 2:i-1:-1], but as you've observed, this cuts off the first character in the string. This is a quirk of slice syntax the end bound of the slice is exclusive rather than inclusive, but at the same time an index of -1 refers to the end of the string rather than 'the character before the beginning' (which would be out of bounds in, say, Java, but in which we wouldn't have this problem). To my knowledge, there's no way around this.

You could also try using reversed() instead of [::-1], but I don't think that makes it any simpler or quicker:

print(''.join(c for i in range(0, len(string), 3) for c in reversed(string[i:i 3])))
  • Related