[Python入門]リストの操作:Python入門(1/4 ページ)
要素数の取得、リストの結合、リストに対する要素の追加と削除、並べ替え、反転、コピーなど、リストを操作する方法をまとめて紹介する。
* 本稿は2019年6月4日、2022年6月24日に公開/改訂された記事を、Python 3.12.0で動作確認したものです(確認日:2023年10月16日)。
前回は、Pythonでよく使われるデータ型であるリストの基本について取り上げた。今回はリストを操作する各種のメソッドや関数などを取り上げる。リストへの要素の追加など、前回触れたものについても重複するが再度掲載する(それらについては簡単にまとめる)。
今回の目次
- リストの要素数を求める:len関数
- 最大/最小の要素の取得:max関数/min関数
- リストの結合と乗算
- リストに特定の要素が含まれているかの確認:in演算子
- 要素が格納されているインデックスの取得:indexメソッド
- 指定した要素が何個リストに格納されているのかのカウント:countメソッド
- リストへの要素の追加:appendメソッド/extendメソッド
- リストへの要素の挿入:insertメソッド
- リストからの要素の削除:del文/removeメソッド/popメソッド/clearメソッド
- リストの並べ替え:sortメソッド/sorted関数
- リストの反転:reverseメソッド/reversed関数
- リストのコピー:copyメソッド
- 「浅いコピー」とは
リストの要素数を求める:len関数
リストの要素数は、文字列の要素数と同じく、len関数で調べられる。
len関数
len(s)
引数に指定したリストsの要素数を返す。
パラメーター | 説明 |
---|---|
s | 要素数を知りたいリスト |
len関数のパラメーター |
なお、len関数は、文字列やリストなど「要素に順序」がある反復可能オブジェクト(これらを「シーケンス」と呼ぶ。そのため、パラメーターリストには「sequence」の最初の文字である「s」を名前としたパラメーターが置かれている)あるいは、辞書や集合など「要素に順序」がないコレクションなどを指定できる。
以下に例を示す(len関数については実行例は省略する)。
intlist = list(range(5))
print(len(intlist)) # 出力結果:5
関数の引数にリストを渡す
上の例ではlen関数にリストをそのまま渡していた。これはlen関数がシーケンスやコレクションを「1つ」だけ受け取り、その要素数を返すという動作をするからだ。しかし、時にはリストをそのまま渡すのではなく、リストの要素を個別の位置引数として渡せると便利なことがある。
今述べたことの例としてはあまり適切ではないが、print関数について考えてみる。リストの要素を画面に出力するには以下のようにするのが一般的だ。
intlist = list(range(5))
print(intlist) # [0, 1, 2, 3, 4]
その一方で、print関数は任意の個数の引数を受け取り、それらを半角空白文字で区切って画面に出力することも可能だ。
print(0, 1, 2, 3, 4) # 0 1 2 3 4
リストの要素を展開して、上の例と同様な形でprint関数に渡すことも可能だ。これにはリスト(が代入されている変数)の前に「*」を前置する。
print(*intlist) # 0 1 2 3 4
このようにリストやタプルといった、複数の値を格納するオブジェクトを関数呼び出し時にバラバラにして渡すことを「引数のアンパック」などと呼ぶ。詳しくは第13回「関数の引数」の「引数のアンパック(展開)」なども参照されたい。
最大/最小の要素の取得:max関数/min関数
リストに格納されている要素から最大のものを取得するにはmax関数を、最小のものを取得するにはmin関数が使える(これも文字列と同様だ)。
max関数/min関数
max(iterable, key, default)
min(iterable, key, default)
指定した反復可能オブジェクトiterableから最大/最小の要素を取得する。パラメーターkeyは、最大/最小の要素を算出する際に使用する「キー」を決定するための関数を受け取る(省略可能)。この関数は引数を1つだけ持つものでなければならない。パラメーターdefaultには、パラメーターiterableが空だった場合の戻り値を指定する。「パラメーターiterableが空」かつ「パラメーターdefaultが指定されなかった」場合にはエラー(ValueError例外)が発生する。
パラメーター | 説明 |
---|---|
iterable | 最大/最小の要素を知りたいリスト |
key | キーワード引数としてのみ指定可能。リストの要素の比較で使用するキーを取り出す1引数の関数(省略可能) |
default | キーワード引数としてのみ指定可能。iterableが空の場合の戻り値(省略可能) |
max関数/min関数のパラメーター |
リストを使って、最大値/最小値を調べる簡単な例を以下に示す(実行結果は省略)。
intlist = [7, 0, -9, 3, 2, -1, -3, 1, -5, 4]
print(max(intlist)) # 出力結果:7
print(min(intlist)) # 出力結果:-9
パラメーターkeyには、リストの要素を引数として受け取る1引数の関数を指定する。実際に最大/最小の要素を算出する際には、各要素をこの関数に渡して得られた値同士が比較される。例えば、上のコードに示したリストで絶対値が最大の要素または最小の要素を知りたいとする。その場合には、組み込みのabs関数をパラメーターkeyに指定する。以下に例を示す。
intlist = [7, 0, -9, 3, 2, -1, -3, 1, -5, 4]
print('max(abs):', max(intlist, key=abs))
print('min(abs):', min(intlist, key=lambda x: -x if x < 0 else x))
実行結果を以下に示す。
この例では、max関数の呼び出しで組み込みのabs関数をキーワード引数の形で渡している。min関数の呼び出しでは同じことをする無名関数をラムダ式を使って渡している。
なお、このラムダ式では「条件式」と呼ばれる式を使って、ラムダ式の戻り値を記述している。「条件式」とは「戻り値1 if 条件 else 戻り値2」という形の式で「条件」が真(True)なら「戻り値1」が返され、「条件」が偽(False)なら「戻り値2」が返される(「戻り値1」「条件」「戻り値2」の3つの項を持つので「三項演算子」と呼ぶこともある)。このとき、「戻り値2」の部分にさらに条件式を置いて、「戻り値1 if 条件1 else 戻り値2 if 条件2 else 戻り値3」のように場合分けを深くすることもできる。
パラメーターdefaultには、パラメーターiterableが空だった場合に戻り値とする値をキーワード引数として渡す。外部(何らかの関数など)から得られた反復可能オブジェクトをmax/min関数に渡す場合には、それが空の場合もある。そうした場合には、最大値も最小値も存在しないので、通常はエラー(ValueError例外)が発生するが、パラメーターdefaultに戻り値を指定しておくと、エラーとはならずにその値が戻り値となる。
print(max([], default='no item')) # デフォルトの戻り値を指定
リストをmax/min関数に渡す場合には、その全要素が「比較可能」である必要がある。例えば、整数値と浮動小数点数値だけを要素とするリストであれば、それらは全て比較できるが、文字列と整数値は比較できない。そのような場合には、パラメーターkeyに型変換を行うint関数やstr関数を指定することが考えられる(ただし、それが意味論的に正しいかは場合によるだろう)。以下に例を示す(実行結果は省略)。
print(min([2, '1'], key=int)) # 要素を整数値に変換して大小を比較
print(max([1, 2, 'foo'], key=str)) # 要素を文字列に変換して大小を比較
print(max([2, '1'])) # エラー
リストの結合と乗算
文字列と同様に、リストも結合や乗算が可能だ。結合に関しては、前回の「リストの結合」でも紹介した。ここでは簡単にこれらをまとめておく。
リストを結合するには「+」演算子を使用する。これは、2つのリストを結合した新しいリストを作成する。一方、リストを乗算するには「*」演算子を使用する。これは「リスト * 整数値」または「整数値 * リスト」の形で記述するもので、リストを「整数値」回繰り返したものが演算結果となる。以下に例を示す(実行結果は省略)。リストの乗算は「同じ値を複数個要素とするリスト」を作成する際に便利に使える。
print([1, 2] + [3, 4]) # リストの結合:[1, 2, 3, 4]が得られる
print(5 * ['a']) # リストの乗算:['a', 'a', 'a', 'a', 'a']が得られる
リストに特定の要素が含まれているかの確認:in演算子
リストに特定の要素が含まれているかを確認するにはin演算子を、含まれていないかを確認するにはnot in演算子を使用する。特定の要素が含まれているかは「調べたい値 in リスト」として確認する。リストに「調べたい値」が含まれていれば演算結果はTrueに、含まれていなければ演算結果はFalseになる。逆に特定の要素が含まれていないことを確認するには「調べたい値 not in リスト」のようにする。その値がリストに含まれていなければ演算結果はTrueとなり、含まれていれば演算結果はFalseになる。
以下に例を示す(実行結果は省略)。
print('foo' in ['foo', 'bar']) # 出力結果:True
print('hoge' not in ['foo', 'bar']) # 出力結果:True
要素が格納されているインデックスの取得:indexメソッド
特定の要素がリストに含まれているか(含まれていないか)どうかの確認には上で述べたin演算子(not in演算子)が使える。だが、含まれている場合に、それが何番目の要素であるかまでを知りたいときには、リストのindexメソッドを使用する。
indexメソッド
リスト.index(item, start, end)
「リスト」に「item」が含まれているかを調べ、含まれていればそのインデックスを返す。「item」が複数含まれているときには、最小のインデックスが返される。「start」と「end」にはリスト内で検索を行う範囲を指定する(インデックスstart〜インデックスend−1の範囲が検索対象となる)。指定した範囲(デフォルトはリストの全要素)に、指定した値が含まれていないときにはエラー(ValueError例外)が発生する。
パラメーター | 説明 |
---|---|
item | リストに含まれているか、含まれているならどこにあるかを調べたい値 |
start | 検索を開始する位置を示すインデックス(省略可能)。省略した場合は先頭から検索を行う |
end | 検索を終了する位置を示すインデックス(省略可能)。省略した場合は末尾まで検索を行う |
indexメソッドのパラメーター |
以下に例を示す。
intlist = [0, 10, 9, 2, -7, -10, -2, -9, -7, 3]
print(intlist.index(-7)) # 出力結果:4(「-2」の最小のインデックス)
print(intlist.index(-7, 5)) # 出力結果:8(インデックス5以降を検索するため)
print(intlist.index(3, 0, 9)) # エラー
実行結果を以下に示す。
最初のindexメソッド呼び出しでは「-7」を検索している。このリストには「-7」が2つ含まれているが、このときには最小のインデックスである「4」が得られる。次の呼び出しでも「-7」を検索しているが、インデックス5以降を検索範囲としているので、1つ目の「-7」ではなく2つ目の「-7」のインデックスである8が返されている。このように、複数の値が含まれているかどうかを調べるときには「直前の呼び出しで得られたインデックス+1」以降を検索範囲として、もう一度indexメソッドを呼び出すこともできる。
最後の呼び出しでは、index関数にstart値として「0」を、stop値として「9」を指定している。そのため、このリストの最終要素(インデックス9)は検索範囲に含まれておらず、リストに「3」が含まれているにもかかわらずエラーとなっている。
指定した要素が何個リストに格納されているかのカウント:countメソッド
特定の要素がリスト中に何個含まれているかを調べるにはcountメソッドが使える。
countメソッド
リスト.count(item)
リストに「item」が何個含まれているかを返す。
パラメーター | 説明 |
---|---|
item | リストに何個含まれているかを知りたい値 |
countメソッドのパラメーター |
以下に例用例を示す。
intlist = [0, 10, 9, 2, -7, -10, -2, -9, -7, 3]
print(intlist.count(1)) # 出力:0
idx = -1
count = intlist.count(-7)
for num in range(count):
idx = intlist.index(-7, idx + 1) # インデックスidx以降を検索範囲とする
print(f'{idx}: {intlist[idx]}') # インデックスとその要素を表示
最初のcountメソッド呼び出しは単純にリストに含まれている整数値「1」が含まれている数を調べているだけだ。次の例では、countメソッドで整数値「-7」が何個含まれているかを調べた上で、for文で「-7」のインデックスを調べるコード例だ。特定の要素が何個含まれているかが最初から分かっていれば、エラー(例外)が発生する不安なしに、このようにして各インデックスを調べられる(最初の検索範囲を「インデックス0」以降として、次の検索範囲を「indexメソッドの戻り値+1」以降としたいので、変数idxの初期値を「-1」としている点にも注意)。実行結果を以下に示す。
ここまでに見てきた操作の多くは文字列とリストで共通のものだ。これは、文字列とリストには「整数値のインデックスを指定して、要素にアクセス可能」という共通の特性があるからだ。文字列やリストなどをまとめて「シーケンス」(順序=インデックスを持った要素が集まったもの)と呼ぶことがある。
その一方で、文字列は変更不可能で、リストは変更可能という違いもある。以下で紹介するのは、リストを変更するためのメソッドや文だ。これらを元のリストを書き換えてしまうことから「破壊的操作」と呼ぶこともある。これに対して、元のリストを書き換えない操作のことを「非破壊的操作」と呼ぶことがある。
Copyright© Digital Advantage Corp. All Rights Reserved.