Complex list slice/index in python

2019-04-06 14:27发布

问题:

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

回答1:

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).



回答2:

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])


回答3:

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]


回答4:

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]


回答5:

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.