4

I have a list, of which I want to extract a subslice from back to end. With two lines of code, this is

mylist = [...]
mysublist = mylist[begin:end]
mysublist = mysublist[::-1]

Is there a slicing notation to get the same effect in one line? This

mysublist = mylist[end:begin:-1]

is incorrect, because it includes the end and excludes the begin elements. This

mysublist = mylist[end-1:begin-1:-1]

fails when begin is 0, because begin-1 is now -1 which is interpreted as the index of the last element of mylist.

3 Answers 3

6

Use None if begin is 0:

mysublist = mylist[end - 1:None if not begin else begin - 1:-1]

None means 'default', the same thing as omitting a value.

You can always put the conditional expression on a separate line:

start, stop, step = end - 1, None if not begin else begin - 1, -1
mysublist = mylist[start:stop:step]

Demo:

>>> mylist = ['foo', 'bar', 'baz', 'eggs']
>>> begin, end = 1, 3
>>> mylist[end - 1:None if not begin else begin - 1:-1]
['baz', 'bar']
>>> begin, end = 0, 3
>>> mylist[end - 1:None if not begin else begin - 1:-1]
['baz', 'bar', 'foo']
Sign up to request clarification or add additional context in comments.

Comments

4

You could simply collapse your two lines into one:

mysublist = mylist[begin:end][::-1]

2 Comments

This still creates two list objects however.
@MartijnPieters it does, but it depends what you're trying to optimize. The mission was to do it "in one line" so I assume readability trumps efficiency. Your solution with the ternary operator is technically unassailable, but I would find it unreadable.
1

You can always use the power of functional transformations:

mysublist = list(reversed(mylist[begin:end]))

1 Comment

reversed() doesn't return a list, it returns an iterator.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.