16

質問を説明する間、しばらくお待ちください。拡張スライス リストのインデックス作成を既に理解している場合は、太字の見出しまでスキップしてください。

Python では、スライス表記を使用してリストにインデックスを付けることができます。次に例を示します。

>>> A = list(range(10))
>>> A[0:5]
[0, 1, 2, 3, 4]

「ステップ」のように機能するストライドを含めることもできます。

>>> A[0:5:2]
[0, 2, 4]

ストライドを負にすることもできます。つまり、要素は逆の順序で取得されます。

>>> A[5:0:-1]
[5, 4, 3, 2, 1]

ちょっと待って!見たかった[4, 3, 2, 1, 0]。なるほど、開始インデックスと終了インデックスをデクリメントする必要があります。

>>> A[4:-1:-1]
[]

どうしたの?-1 は、配列の先頭ではなく末尾にあると解釈しています。私はあなたが次のようにこれを達成できることを知っています:

>>> A[4::-1]
[4, 3, 2, 1, 0]

ただし、すべての場合にこれを使用できるわけではありません。たとえば、インデックスが渡されたメソッドで。

私の質問は:

シーケンスの最初の要素を含む負のストライドと明示的な開始インデックスと終了インデックスを持つ拡張スライスを使用する良い Pythonic の方法はありますか?

これは私がこれまでに思いついたものですが、満足のいくものではないようです。

>>> A[0:5][::-1]
[4, 3, 2, 1, 0]
4

9 に答える 9

5

と のセマンティクスを変更するとエラーが発生しやすくなりstartますstopNoneまたは-(len(a) + 1)の代わりに0またはを使用し-1ます。セマンティクスは任意ではありません。Edsger W. Dijkstra の記事「Why numbering should start at zero」を参照してください。

>>> a = range(10)
>>> start, stop, step = 4, None, -1

または

>>> start, stop, step = 4, -(len(a) + 1), -1
>>> a[start:stop:step]
[4, 3, 2, 1, 0]

または

>>> s = slice(start, stop, step)
>>> a[s]
[4, 3, 2, 1, 0]

シーケンスの場合s、ネガティブインデックスはs[i:j:k]特別に扱われます。

iorが負の場合j、インデックスは文字列の末尾からの相対値になります: len(s) + iorlen(s) + jが置換されます。-0しかし、まだであることに注意してください0

len(range(10)[4:-1:-1]) == 0同等だからrange(10)[4:9:-1]です。

于 2008-12-30T12:06:23.797 に答える
2

わかりました、これはおそらく私が手に入れるのと同じくらい良いと思います。アイデアを思いついた Abgan に感謝します。これは、スライス内の None が欠落したパラメーターであるかのように扱われるという事実に依存しています。誰かがより良いものを得ましたか?

def getReversedList(aList, end, start, step):
    return aList[end:start if start!=-1 else None:step]

編集: を確認しますstart==-10

これはまだ理想的ではありません。これは、-1 の通常の動作を無効にしているためです。ここでの問題は、何が起こるべきかについての 2 つの重複する定義にあるようです。どちらが勝ったとしても、他の意図を探して、そうでなければ有効な呼び出しを奪います。

于 2008-12-29T23:44:35.417 に答える
2
[ A[b] for b in range(end,start,stride) ]

遅くなりますが、負のインデックスを使用できるため、これは機能するはずです。

[ A[b] for b in range(9, -1, -1) ]

これはスライスを使用していないことに気づきましたが、特に結果を得るためにスライスを使用することが優先されない場合は、とにかく解決策を提供すると思いました。

于 2008-12-30T00:10:05.550 に答える
1

ただし、たとえばインデックスを変数に格納している場合は、それを使用できません。

これで満足ですか?

>>> a = range(10)
>>> start = 0
>>> end = 4
>>> a[4:start-1 if start > 0 else None:-1]
[4, 3, 2, 1, 0]
于 2008-12-30T11:41:43.067 に答える
1

以下はあなたを満足させないと思います:

def getReversedList(aList, end, start, step):
    if step < 0 and start == 0:
         return aList[end::step]
    return aList[end:start:step]

またはそれはありますか?:-)

于 2008-12-29T23:38:30.310 に答える
1

あなたが言うように、拡張スライスでできることすべてを完全に理解している人はほとんどいないので、追加のパフォーマンスが本当に必要でない限り、「明白な」方法で行います。

rev_subset = reversed(data[start:stop])

于 2008-12-30T15:01:08.077 に答える
0

これは古い質問であることは知っていますが、私のような人が答えを探している場合:

>>> A[5-1::-1]
[4, 3, 2, 1, 0]

>>> A[4:1:-1]
[4, 3, 2]
于 2011-01-04T23:17:45.280 に答える
0

slice(start, stop, step)次のようなオブジェクトを使用できます。

s=slice(start, stop, step)
print a[s]

と同じです

print a[start : stop : step]

さらに、引数のいずれかを設定してNone、コロンの間に何も示さないようにすることができます。したがって、与える場合は、 を使用できますslice(4, None, -1)

于 2011-01-04T23:52:24.850 に答える
0
a[4::-1]

例:

Python 2.6 (r26:66714, Dec  4 2008, 11:34:15) 
[GCC 4.0.1 (Apple Inc. build 5488)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> a = list(range(10))
>>> a
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> a[4:0:-1]
[4, 3, 2, 1]
>>> a[4::-1]
[4, 3, 2, 1, 0]
>>> 

その理由は、第 2 項が「while not index ==」と解釈されるためです。それを省略するのは「while index in range」です。

于 2008-12-29T23:33:18.417 に答える