Pyrhon♪リストのインデックス指定とスライス。stepが負のときは注意!

スライスは要素の一部を指定できるだけでなく、逆順に並び替えたりすることも出来ます。リストを扱うときに大変便利な機能ですので使い方を整理したいと思います。特にstepがマイナスのときの範囲指定の方法はチュートリアルの図では間違えてしまいますので注意する必要があります。

0.チュートリアル学習のポイントシリーズ

この記事は「Pythonチュートリアルのポイント整理シリーズ」の記事です。一連の記事は、以下のリンク集を参照してください。
「Pythonチュートリアル」のポイント整理シリーズ

1.インデックスによる要素の直接指定

 それでは、インデックス指定により要素を直接指定してみましょう。インデックスは下図のように一番左が0になり、右側になるほど大きな値になります。一方、負のインデックスで指定する場合は一番右側が-1になり、左側になるほど小さな値になります。

では、実際にインデックスを指定して要素を出力してみましょう。

#コード01
x = ['a', 'b', 'c', 'd', 'e']
print('x[0] =', x[0])
print('x[1] =', x[1])
print('x[2] =', x[2])
print('x[3] =', x[3])
print('x[4] =', x[4])
print('x[-1] =', x[-1])
print('x[-2] =', x[-2])
print('x[-3] =', x[-3])
print('x[-4] =', x[-4])
print('x[-5] =', x[-5])
#出力01
x[0] = a
x[1] = b
x[2] = c
x[3] = d
x[4] = e
x[-1] = e
x[-2] = d
x[-3] = c
x[-4] = b
x[-5] = a

2.要素の範囲指定

 次に、スライスによる要素の範囲指定です。 スライスで範囲指定する時の書式は下式のようになります。 startとstopで範囲を指定し、stepで増分ステップを指定します。

(1) stepが1の場合

覚え方はいくつかありますが、インデックス指定のときに使った図をそのまま使う方法が最も簡単だと思います。具体例を見ながら説明します。

下図のように、リストx=['a', 'b', 'c', 'd', 'e']の['b', 'c']の部分を指定するにはx[1:3]とします。 x[1:3] は「インデックス1」の要素から「インデックス3」の1つ手前の「インデックス2」までの要素をリストにします。なお、stepは1なので、x[1:3:1]を省略してx[1:3]とできます。

また、負のインデックスで示すこともでき、x[-4, -2]も「インデックス-4」から「インデックス-2」の1つ手前の「インデックス-3」までの要素をリストにし、['b', 'c']となります。

#コード02
x = ['a', 'b', 'c', 'd', 'e']
print('x[1:3] =', x[1:3])
print('x[-4:-2] =', x[-4:-2])
#出力02
x[1:3] = ['b', 'c']
x[-4:-2] = ['b', 'c']

(2) stepが負の場合

増分ステップが負の場合は以下のように指定します。先ほどの出力02は['b', 'c']でしたが、出力03はstepが-1なので['c', 'b']と要素が逆になっていることに注意してください。

#コード03
x = ['a', 'b', 'c', 'd', 'e']
print('x[2:0:-1] =', x[2:0:-1])
print('x[-3:-5:-1] =', x[-3:-5:-1])
#出力03
x[2:0:-1] = ['c', 'b']
x[-3:-5:-1] = ['c', 'b'])

(3) stepが2や-2の場合

stepが2や-2の場合のコードを紹介します。出力が1つ飛ばしになっているのがわかります。

#コード04
x = ['a', 'b', 'c', 'd', 'e']
print('x[0:4:2] =', x[0:4:2]) 
print('x[-1:-5:-2] =', x[-1:-5:-2]) 
#出力04
x[0:4:2] = ['a', 'c']
x[-1:-5:-2] = ['e', 'c']

(4) 正負のインデックスを混在させることも可能

こんな書き方をすることはないと思いますが、正負のインデックスを混在させることも可能です。下の例のx[1:-2]、x[-4:3]は、要素の指定範囲がそれぞれ「1と-2」「-4と3」であり、正負が混在しています。

#コード05
x = ['a', 'b', 'c', 'd', 'e']
print('x[1:-2] =', x[1:-2])
print('x[-4:3] =', x[-4:3])
#出力05
x[1:-2] = ['b', 'c']
x[-4:3] = ['b', 'c']

(5) startとstopを逆にすると

誤って、startとstopを逆にしてもエラーにはなりませんが、要素がない空のリストになってしまいます。

#コード06
x = ['a', 'b', 'c', 'd', 'e']
print('x[1:3] =', x[1:3])
print('x[3:1] =', x[3:1])
#出力06
x[1:3] = ['b', 'c']
x[3:1] = []

(6) 1番右の要素も指定する場合

1番右の要素を指定する場合、x[3:5]、x[3:999]のように、stopを1番右の要素のインデックスよりも大きな値にします。

あるいは省略してx[3:]、x[-2:]のようにすることもできます。

なお、「インデックス-1」の右側が「インデックス0」であると勘違いしてx[-2:0]のような記述をすると、空のリストになってしまいます。

「インデックス0」と「インデックス-1」の位置は隣同士ではないので、注意してください。

#コード07
x = ['a', 'b', 'c', 'd', 'e']
print('x[3:5] =', x[3:5])
print('x[3:999] =', x[3:999])
print('x[3:] =', x[3:])
print('x[-2:] =', x[-2:])
print('x[-2:0] =', x[-2:0])
#出力07
x[3:5] = ['d', 'e']
x[3:999] = ['d', 'e']
x[3:] = ['d', 'e']
x[-2:] = ['d', 'e']
x[-2:0] = []

(7) 1番左の要素も指定する場合

1番左の要素も指定する場合も同様です。

#コード08
x = ['a', 'b', 'c', 'd', 'e']
print('x[-4:-6:-1] =', x[-4:-6:-1])
print('x[-4:-999:-1] =', x[-4:-999:-1])
print('x[-4::-1] =', x[-4::-1])
print('x[1::-1] =', x[1::-1])
print('x[1:-1:-1] =', x[1:-1:-1])
#出力08
x[-4:-6:-1] = ['b', 'a']
x[-4:-999:-1] = ['b', 'a']
x[-4::-1] = ['b', 'a']
x[1::-1] = ['b', 'a']
x[1:-1:-1] = []

3.チュートリアルの方法は要注意

チュートリアルでは、下のような図がのっています。確かにこれだと「1つ手前」といった覚え方をしなくてよいのですが、stepがマイナスの場合は別の図を覚えなければなりません。

下の図のように、stepがマイナスの場合は、0が左から2番目、右端が-1になってしまいます。私はインデックス指定と同じ図を使った方が覚えやすいのではないかと思います。

#コード09
x = ['a', 'b', 'c', 'd', 'e']
print('x[1:3] =', x[1:3])  #増分が正
print('x[-4:-2] =', x[-4:-2])  #増分が正
print('x[2:0-1] =', x[2:0-1])  #増分が負
print('x[-3:-5:-1] =', x[-3:-5:-1])  #増分が負
#出力09
x[1:3] = ['b', 'c']
x[-4:-2] = ['b', 'c']
x[2:0-1] = ['c', 'd']
x[-3:-5:-1] = ['c', 'b']

4.省略についてのまとめ

スライスの書式は下式のようになりますが、start, stop, stepはそれぞれ省略出来る場合がありますので、整理したいと思います。

(1) 省略できる場合とは

(a) stepが1のときは手前のコロンといっしょに省略できる。 x[2:4]

(b-1) stepが正のとき、startを省略すると1番左の要素から選択される 。 x[:4]
(b-2) stepが正のとき、stopを省略すると1番右の要素まで選択される。 x[2:]

(c-1) stepが負のとき、startを省略すると1番右の要素から選択される。x[:-4:-1]
(c-2) stepが負のとき、stopを省略すると1番左の要素まで選択される。x[-2::-1]

(2) 具体例

コード10は、省略した具体例です。なお、出力の一番右側は省略する前の書式です。同じ出力結果になっているのがわかります。

なお、コード10の14行目のようにx[::-1]とすると、リストの要素の順番を反転することができます。

#コード10
x = ['a', 'b', 'c', 'd', 'e']
#よく使われる省略形
print('x[2:4] ='   , x[2:4]   , x[2:4:1])
print('x[:4] ='    , x[:4]    , x[0:4:1])
print('x[2:] ='    , x[2:]    , x[2:5:1])
print('x[:] ='     , x[:]     , x[0:5:1])
#以下のような省略も可能
print('x[:4:2] ='  , x[:4:2]  , x[0:4:2])
print('x[1::2] ='  , x[1::2]  , x[1:5:2])
print('x[::2] ='   , x[::2]   , x[0:5:2])
print('x[:-4:-1] =', x[:-4:-1], x[-1:-4:-1])
print('x[-2::-1] =', x[-2::-1], x[-2:-6:-1])
print('x[::-1] ='  , x[::-1]  , x[-1:-6:-1])
#出力10
x[2:4] = ['c', 'd'] ['c', 'd']
x[:4] = ['a', 'b', 'c', 'd'] ['a', 'b', 'c', 'd']
x[2:] = ['c', 'd', 'e'] ['c', 'd', 'e']
x[:] = ['a', 'b', 'c', 'd', 'e'] ['a', 'b', 'c', 'd', 'e']
x[:4:2] = ['a', 'c'] ['a', 'c']
x[1::2] = ['b', 'd'] ['b', 'd']
x[::2] = ['a', 'c', 'e'] ['a', 'c', 'e']
x[:-4:-1] = ['e', 'd', 'c'] ['e', 'd', 'c']
x[-2::-1] = ['d', 'c', 'b', 'a'] ['d', 'c', 'b', 'a']
x[::-1] = ['e', 'd', 'c', 'b', 'a'] ['e', 'd', 'c', 'b', 'a']

省略したところが分かるように色を付けて比較してみました。

x = ['a', 'b', 'c', 'd', 'e']
#よく使われる省略形
x[2:4]   , x[2:4:1])
x[:4]    , x[0:4:1])
x[2:]    , x[2:5:1])
x[:]     , x[0:5:1])
#以下のような省略も可能
x[:4:2]  , x[0:4:2])
x[1::2]  , x[1:5:2])
x[::2]   , x[0:5:2])
x[:-4:-1], x[-1:-4:-1])
x[-2::-1], x[-2:-6:-1])
#要素の反転
x[::-1]  , x[-1:-6:-1])

5.その他の範囲指定

スライス以外でも範囲指定する関数はたくさんありますので、比較のために紹介します。

(1) range()関数

range()も、よく使う関数だと思いますが、スライスと同じような感覚で覚えられます。

 基本:range()の基本的な使い方は完璧に覚えておこう。

(2)リストのindex()メソッド

list.index(x, i, j)はリスト(list)の要素の中で最初に出現するxのインデックス番号を返します。

list.index(x, i, j)のi, jが、範囲を指定する部分ですが、スライスと同様にiの位置から、jの1つ手前の位置までの範囲を検索します。

したがって、コード11のようにx.index('c', 0, 2)とすると、リストx = ['a', 'b', 'c', 'd', 'e']のインデックス番号が0~1の範囲に'c'が見つからず、エラーになります。

#コード11
x = ['a', 'b', 'c', 'd', 'e']
print(x.index('c', 0, 2))
#出力11
ValueError: 'c' is not in list

このようにPythonの関数で範囲を指定する場合には、その数字が入るか入らないかを注意する必要があります。

私が実際に購入した教材のご紹介

以下、私が実際に購入したPythonの教材をまとめてみました。 Pythonを学習する上で、少しでもお役に立つことができればうれしいです。

Python♪私が購入したPythonの書籍のレビュー
UdemyのPythonの動画講座を書籍を買う感覚で購入してみた

その他

Twitterへのリンクです。SNSもはじめました♪

液晶ペンタブレットを買いました
 (1) モバイルディスプレイを買うつもりだったのに激安ペンタブレット購入

以下、私が光回線を導入した時の記事一覧です。
 (1) 2020年「光回線は値段で選ぶ」では後悔する ←宅内工事の状況も説明しています。
 (2) NURO光の開通までWiFiルーターを格安レンタルできる
 (3) NURO光の屋外工事の状況をご紹介。その日に開通!
 (4) 光回線開通!実測するとNURO光はやっぱり速かった
 (5) ネット上のNURO光紹介特典は個人情報がもれないの?