I wanted to recursively reverse elements in the list for range i
to j
.
def revlist(l, i, j):
if not l: # this will be true if l == []
return l
return l[-1:] revlist(l[:-1]) # recursive case
For example list [1, 2, 3, 4, 5, 6, 7, 8, 9]
for i = 2
and j = 5
will be [1, 5, 4, 3, 2, 6, 7, 8, 9]
.
How to do this?
CodePudding user response:
If you insist on a recursive implementation (which is inefficient, and rather pointless in this use case, as well as limiting the size of the list that can be reversed):
def rev_sublist(xs, i, j):
def rec_rev(ys):
if not ys:
return ys
else:
return [ys[-1]] rec_rev(ys[:-1])
return xs[:i] rec_rev(xs[i:j]) xs[j:]
print(rev_sublist([1, 2, 3, 4, 5, 6, 7, 8, 9], 2, 5))
If you don't like the idea of the inner function here, the logic will become very convoluted, something like:
def rev_sublist(xs, i, j):
if i >= j:
return xs
else:
return rev_sublist(xs[:i] [xs[j-1]] xs[i:j-1] xs[j:], i 1, j)
print(rev_sublist([1, 2, 3, 4, 5, 6, 7, 8, 9], 2, 5))
But if this was a programming class and I asked you to write a routine to reverse lists and you came up with this, I'm about to fail you.
Note: you say "in range i
to j
" - in Python, a range is generally not inclusive of j
and list indexing starts at 0. So, in the above examples, the ouput would be:
[1, 2, 5, 4, 3, 6, 7, 8, 9]
This does not match your example that seems to want to include j
and start indexing at 1
, which would make your code extremely unpythonic and just wrong from my perspective as a professional software developer. But of course you could easily update the indices if you wanted to match that.
Also note that, the choice of 'range' is yours - for a function like rev_sublist
I don't think making j
inclusive is a bad idea - in fact, I'd probably prefer it.
Here's a solution without recursion (using the same convention as above):
def rev_sublist(xs, i, j):
return xs[:i] xs[j-1:i-1:-1] xs[j:]
Which makes it pretty obvious why a recursive solution is a bad one.
If I were to write this function and the interface wasn't set in stone, I'd probably prefer:
def rev_sublist(xs, i, j):
return xs[:i] xs[j:i-1:-1] xs[j 1:]
Which would return [1, 2, 6, 5, 4, 3, 7, 8, 9]
for the above example. (also note that it's exactly the same as the solution independently proposed by user @MichaelM. which reinforces the idea that it's the more or less obvious implementation in Python)
CodePudding user response:
You don't need to use recursion here. Just use the built-in .reverse()
method for a slice of the original list. You can do it like this:
def reverseSlice(lst, i, j):
return lst[:i] lst[j:i-1:-1] lst[j 1:]
lst = [1, 2, 3, 4, 5]
print(reverseSlice(lst, 2, 4)) # => [1, 2, 5, 4, 3]