8

I have a list that looks like this:

lst = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]

I'd like to generate a filtered list that looks like this:

filtered_lst = [2, 6, 7, 9, 10, 13]

Does Python provide a convention for custom slicing. Something such as:

lst[1, 5, 6, 8, 9, 12] # slice a list by index

5 Answers 5

17

Use operator.itemgetter():

from operator import itemgetter

itemgetter(1, 5, 6, 8, 9, 12)(lst)

Demo:

>>> from operator import itemgetter
>>> lst = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
>>> itemgetter(1, 5, 6, 8, 9, 12)(lst)
(2, 6, 7, 9, 10, 13)

This returns a tuple; cast to a list with list(itemgetter(...)(lst)) if a that is a requirement.

Note that this is the equivalent of a slice expression (lst[start:stop]) with a set of indices instead of a range; it can not be used as a left-hand-side slice assignment (lst[start:stop] = some_iterable).

Sign up to request clarification or add additional context in comments.

11 Comments

With a slice you can modify the underlying list. Can you do that with itemgetter?
*mumble mumble* "one way to do it" *mumble mumble mumble* ;)
@DavidHeffernan: You cannot use it as a left-hand assignment target, no.
Since the question explicitly mentions slicing, perhaps you should mention left-hand assignment in the answer
@DavidHeffernan: 'slice' could also mean an extended slice (not supported by python the list type), which does allow for a [index1, index2, .., indexn] notation. The result of a slice expression is a new list, and that's what I think the OP is after. :-) The other use of a slice is as an assignment target, which is what I think you mean, and that is very much out of scope here. Just getting our terminology sorted out here, I think! :-)
|
5

Numpy arrays have this kind of slicing syntax:

In [45]: import numpy as np

In [46]: lst = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13])

In [47]: lst[[1, 5, 6, 8, 9, 12]]
Out[47]: array([ 2,  6,  7,  9, 10, 13])

Comments

2

It's easily and straightforwardly done using a list comprehension.

lst = range(1, 14)
indices = [1, 5, 6, 8, 9, 12]
filtered_lst = [lst[i] for i in indices]

Comments

1

I'd go with the operator.itemgetter() method that Martijn Pieters has suggested, but here's another way (for completeness)

In [23]: lst = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]

In [24]: indices = set([1, 5, 6, 8, 9, 12])

In [25]: [n for i,n in enumerate(lst) if i in indices]
Out[25]: [2, 6, 7, 9, 10, 13]

Comments

0

A Python slice allows you to make the slice the target of an assignment. And the Python slicing syntax does not allow for slices with irregular patterns of indices. So, if you want to make your "custom" slice the target of an assignment, that's not possible with Python slice syntax.

If your requirements are met by taking a copy of the specified elements, then operator.itemgetter() meets your needs. If you need slice assignment, then numpy slices are a good option.

Comments

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.