web-dev-qa-db-ja.com

Python任意のインデックスによるリストのスライス

Pythonのリストから任意のインデックスを抽出するより良い方法はありますか?

私が現在使用している方法は次のとおりです。

a = range(100)
s = [a[i] for i in [5,13,25]]

ここで、aはスライスする配列、[5,13,​​25]は取得する要素です。 Matlabの同等のものよりもはるかに冗長に見えます:

a = 0:99;
s = a([6,14,26])
40
Ben Hamner
>>> from operator import itemgetter
>>> a = range(100)
>>> itemgetter(5,13,25)(a)
(5, 13, 25)
46
John La Rooy

MatlabユーザーでPythonを使用したい場合は、 numpy を確認してください。

In [37]: import numpy as np

In [38]: a = np.arange(100)

In [39]: s = a[[5,13,25]]

In [40]: s
Out[40]: array([ 5, 13, 25])

これが NumPyとMatlabの比較 であり、こちらが一般的な MatlabコマンドとNumPyでの同等物 の表です。

22
unutbu

「既製」の方法はありません。その方法は非常に巧妙であり、使用できます。コード全体に多くのコードがある場合は、MATLABのように構文を使用するリストのサブクラスを使用することをお勧めします。これは数行のコードで行うことができ、主な負担は作業する必要があることです。組み込みリストではなく、常にこの新しいクラスを使用してください。

class MyList(list):
    def __getitem__(self, index):
        if not isinstance(index, Tuple):
            return list.__getitem__(self, index)
        return [self[i] for i in index]

そしてコンソールで:

>>> m = MyList(i * 3 for i in range(100))
>>> m[20, 25,60]
[60, 75, 180]
11
jsbueno

これは、優れた承認済みの@John La Rooy answer のより堅牢なバージョンです。提供されたdoctestに合格します。常にリストを返します。

def slice_by_index(lst, indexes):
    """Slice list by positional indexes.

    Adapted from https://stackoverflow.com/a/9108109/304209.

    Args:
        lst: list to slice.
        indexes: iterable of 0-based indexes of the list positions to return.

    Returns:
        a new list containing elements of lst on positions specified by indexes.

    >>> slice_by_index([], [])
    []
    >>> slice_by_index([], [0, 1])
    []
    >>> slice_by_index(['a', 'b', 'c'], [])
    []
    >>> slice_by_index(['a', 'b', 'c'], [0, 2])
    ['a', 'c']
    >>> slice_by_index(['a', 'b', 'c'], [0, 1])
    ['a', 'b']
    >>> slice_by_index(['a', 'b', 'c'], [1])
    ['b']
    """
    if not lst or not indexes:
        return []
    slice_ = itemgetter(*indexes)(lst)
    if len(indexes) == 1:
        return [slice_]
    return list(slice_)
0