sec02 - listのメソッド

初心者が覚えておくべきlistのメソッドを9つ紹介します。

スポンサーリンク

append()

append()メソッドは、listに要素を1つ追加する、最も基本的な操作になります。

書式はsample_list.append(x)で、listの末尾に要素を追加します。sample_list[len(a):] = [x]と同じ挙動になりますが、メソッドで記述した方がシンプルで読みやすいコードになります。

sample_list = ['a', 'b', 'c']
sample_list.append('d')
print(sample_list)  # ['a', 'b', 'c', 'd']

append()メソッドは、イテラブルなデータを追加する時は、展開せずにそのまま挿入します。次のコードを実行して確認してみましょう。

sample_list = ['a', 'b', 'c']
sample_list.append(['d', 'e'])
print(sample_list)  # ['a', 'b', 'c', ['d', 'e']]

append()メソッドの注意点は、要素を追加する処理は破壊的変更になることです。つまり、元のlistに対して直接変更が行われるので、元に戻せません。元のlistに戻す必要がある場合は、listをコピーしておくなどの対処が必要です。(listのコピーについては専用のレクチャーで解説します。)

insert()

insert()メソッドは、任意の位置に要素を追加できます。

末尾に新しい要素を追加するのであれば、append()メソッドを使った方が分かりやすく簡潔に書けますが、末尾以外の位置に追加するのであれば、insert()メソッドを使うことになります。

書式はsample_list.insert(n, x) で、要素番号[n]に要素xを追加します。

sample_list = ['a', 'b', 'c']
sample_list.insert(1, 'ab')
print(sample_list)  # ['a', 'ab', 'b', 'c']

上記コードは、要素番号[1]の部分に'ab'を挿入しています。指定位置以降の要素は右にずれます。今回の例ですと、[1]以降の要素である'b''c'は1つずつ右にずれています。

insert()メソッドはappend()メソッドと同じく、イテラブルなデータを追加する時は、展開せずにそのまま挿入します。次のコードを実行して確認してみましょう。

sample_list = ['a', 'b', 'c']
sample_list.insert(1, ['aa', 'bb'])
print(sample_list)  # ['a', ['aa', 'bb'], 'b', 'c']

insert()メソッドの注意点・補足事項は次の通りです。

  1. append()メソッドと同じで、要素を追加する処理は破壊的変更になる
  2. 要素番号の指定は[-1]のように、マイナスの値で指定することもできる
  3. sample_list.insert(len(sample_list),x)と記述すると末尾に要素を追加できるが、コードを書く段階で要素を追加する場所が末尾と決まっている場合はappend()メソッドを使った方が分かりやすい
スポンサーリンク

extend()

extend()末尾に要素を追加するメソッドですが、append()insert()と違う部分は次の通りです。

  • イテラブルなデータを引数として渡さなければならない
  • イテラブルなデータを展開して追加する

書式はsample_list.extend(iterable) で、要素を展開して末尾に追加します。sample_list[len(a):] = iterableと同じ挙動ですが、メソッドを使用することで要素が展開されることが明確になります。("extend"という単語は、"広げる・展開する"という意味。)

sample_list = ['a', 'b', 'c']
sample_list.extend(['d', 'e', 'f'])
print(sample_list)  # ['a', 'b', 'c', 'd', 'e', 'f']

extend()メソッドの注意点・補足事項は次の通りです。

  1. 引数に数値などのイテラブルでないデータを渡すとエラーになる
  2. listの内容が直接変更される、破壊的な更新

remove()

remove()メソッドの書式はsample_list.remove(x)で、xと等しい値を持つ最初の要素を取り除きます。

sample_list = ['a', '--', 'b', 'c']
sample_list.remove('--')
print(sample_list)  # ['a', 'b', 'c']

remove()メソッドの注意点・補足事項は次の通りです。

  1. xが複数存在する場合でも取り除かれるのは1つのみで、他の要素xは残る
  2. 存在しない要素を指定するとエラーになる
  3. listの内容が直接変更される、破壊的な更新

もし、複数ある値をエラー無く全て取り除きたい場合は次のようにコードを書く必要があります。(まだ学習していないwhileが含まれています。whileのレクチャーの中でも、このコードについて触れます。)

sample_list = ['a', '--', 'b', 'c', '--']

while '--' in sample_list:
    sample_list.remove('--')

print(sample_list)  # ['a', 'b', 'c']

listに要素xが存在するかを確認する場合は次のように書きます。(詳細は、"制御フロー"セクションの中で解説します。)

'--' in sample_list

書式x in sample_listは、要素xが存在していたらTrue、存在していなければFalseを返します。

whileの他にも、if文と組み合わせることで、要素xの存在の有無で処理を分岐させることができます。(if文についても、"制御フロー"セクションの中で詳しく解説します。)

sample_list = ['a', '--', 'b', 'c']
if '--' in sample_list:
    # 要素が存在する場合の処理
    print("'--' is in the list.")
else:
    # 要素が存在しない場合の処理
    print("'--' is not in the list.")

pop()

pop()メソッドは、要素番号で指定された位置の要素をlistから取り除き取り除いた値を返します。指定する要素番号は[-1]のようにマイナスの値で指定できます。

pop()メソッドの注意点・補足事項は次の通りです。

  1. 要素番号が指定されない場合、sample_list.pop()はlistの末尾の要素を取り除きます
  2. listが空(要素数が0)であるか、指定した要素番号がlistの範囲外の場合はエラーになります
  3. listの内容が直接変更される、破壊的な更新
# 要素番号を指定しない場合は、最後の要素を取り除く
sample_list = ['a', 'b', 'c']
result = sample_list.pop()
print(sample_list)  # ['a', 'b']
print(result)  # 'c' (取り除かれた要素を返す)

#======================
# 要素番号を指定して取り除く
sample_list = ['a', 'b', 'c']
result = sample_list.pop(1)
print(sample_list)  # ['a', 'c']
print(result)  # 'b' (取り除かれた要素を返す)

上記コードの1つ目の例では、pop()メソッドに引数を渡していません。この場合は1番最後の要素が取り除かれます。そして、取り除かれた要素の値が変数"result"へ代入されます。

2つ目の例では、pop(1)のように、要素番号を引数として渡しています。この場合はsample_list[1]の要素が取り除かれ、取り除かれた要素の値が変数"result"へ代入されます。

もし、pop(n)の書式で要素を取り除こうとした時に、エラーで処理が止まらないようにするには、次の2つの方法があります。

# listに要素が存在し、指定した要素番号が範囲内であることを調べる方法
sample_list = ['a', 'b', 'c']
index = 2
length = len(sample_list)
if sample_list and -length <= index < length:
    result = sample_list.pop(index)
else:
    result = None
print(sample_list)
print(result)

#======================
# try-exceptでチェックする方法
sample_list = ['a', 'b', 'c']
index = -4
try:
    result = sample_list.pop(index)
except IndexError:
    result = None
print(sample_list)
print(result)

いずれの書式も、まだ学習していない内容が含まれているため、"制御フロー"セクションの講義が終わった後で復習しに戻ってきてください。現時点では、『pop(n)は条件によってはエラーで止まってしまうが、その回避方法がある』という事を知っていただければ問題ありません。

index()

index()メソッドは、指定した値と等しい要素を検索し、存在する場合は最初に見つかった要素番号を返します。もし、指定した値と等しい要素がlistの中に存在しなかった場合はエラーになります。

記法は3種類あり、『検索する要素のみ引数に渡す場合』、『検索する要素とstartの位置を指定する場合』、『検索する要素とstart, endの位置を指定する場合』があります。

  • index(x)
    • listの全範囲からxと等しい値を検索する
  • index(x, start)
    • list[start:]の範囲からxと等しい値を検索する
  • index(x, start, end)
    • list[start:end]の範囲からxと等しい値を検索する

任意の引数である"start"と"end"はスライス記法として解釈され、listの探索範囲を指定できます。この時返される要素番号は、"start"からの相対位置ではなく、list全体の先頭からの位置になります。

まずは、"start"と"end"を指定しない場合のコードを確認してみましょう。

sample_list = ['a', 'b', 'c', 'a']
result = sample_list.index('a')
print(result)  # 0 (index() は要素の位置を返します。)

上記コードの実行結果は"0"になります。最初に見つかった'a'の要素番号を返します。

次に、"start"のみ指定した場合のコードを確認してみましょう。

sample_list = ['a', 'b', 'c', 'a']
result = sample_list.index('a', 1)
print(result)  # 3 (index() は要素の位置を返します。)

上記コードの場合は、sample_list[1:]の範囲で検索を行うため、最初([0])の'a'は無視され、2番目([3])の'a'が検索に引っかかります。実行結果は"3"になります。

次に、"start"と"end"を指定する場合のコードを確認してみましょう。

sample_list = ['a', 'b', 'c', 'a']
result = sample_list.index('a', 1, 3)
print(result)  # error (index() は、指定された範囲内に要素が見つからない場合、エラーを発生させます。)

上記コードの場合、sample_list[1:3]の範囲で検索を行います。最初([0])の'a'は無視され、2番目([3])の'a'は検索の範囲外となるため、エラーになります。もし、最後の要素まで検索させたい場合は、"end"の指定は省略しましょう。

count()

count()メソッドは、list内の要素のうち、指定された値と等しい要素の数を返します。

sample_list = ['a', 'b', 'c', 'a']
result = sample_list.count('a')
print(result)  # 2

上記コードの場合、listに'a'が2つ存在するため、実行結果は"2"になります。

count()メソッドは、要素が存在しない場合はエラーにならずに"0"を返します。

sample_list = ['a', 'b', 'c', 'a']
result = sample_list.count('z')
print(result)  # 0

sort()

sort()の基本

sort()メソッドは、リストの要素を昇順に並べ替えます。降順に並べ替えるには、reverse=Trueを指定します。 (reverse=Trueのような引数の記述方法については、"制御フロー"セクションの"関数の引数"についてのレクチャーの中で詳しく解説します。)

sort()メソッドの処理は、元のlistを変更する、破壊的な更新になります。

# 昇順に並べ替える
sample_list = ['c', 'a', 'b', 'e', 'd', 'h', 'g', 'j', 'i', 'f']
sample_list.sort()
print(sample_list)  # ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']

# 降順に並べ替える
sample_list = ['c', 'a', 'b', 'e', 'd', 'h', 'g', 'j', 'i', 'f']
sample_list.sort(reverse=True)
print(sample_list)  # ['j', 'i', 'h', 'g', 'f', 'e', 'd', 'c', 'b', 'a']

sort()のkey引数

sort()メソッドは、"key"引数を指定することができます。

"key"を指定しなければ要素を直接比較して並び替えます(デフォルトの挙動)が、指定することで各要素から比較用のデータ(キー)を展開することができます。例えば、 key=str.lower のように指定することで、文字列を全て小文字に変換したうえで、それらを比較して並び替えることができます。(元のlistの要素は変更されずに、並び替えの比較対象として考慮されます。)

まずは、"key"を指定しない、次のコードを実行してみましょう。

sample_list = ['c', 'C', 'A', 'b', 'a', 'B']
sample_list.sort()
print(sample_list)  # ['A', 'B', 'C', 'a', 'b', 'c']

上記コードの"sample_list"に代入されたlistの要素は、大文字の'A', 'B', 'C'と小文字の'a', 'b', 'c'になります。これをそのまま並び替えると、['A', 'B', 'C', 'a', 'b', 'c']のようになり、先に大文字の'A', 'B', 'C'が並びます。これは正常な挙動で、プログラミング言語は文字コードの順番で並び替えを行います。文字コードは"大文字 -> 小文字"の順に並んでいるため、実行結果は"'A', 'B', 'C' -> 'a', 'b', 'c'"の順に並びます。

次に、"key"を指定したコードを実行してみましょう。

sample_list = ['c', 'C', 'A', 'b', 'a', 'B']
sample_list.sort(key=str.lower)
print(sample_list)  # ['A', 'a', 'b', 'B', 'c', 'C']

上記コードでは、"key"をkey=str.lowerのように指定してます。str.lowerは、string型のlowerメソッドを各要素に適用することを指示しています。この時に気を付けなければならないのは、lower()のように丸カッコは記述しません。丸カッコを付けてしまうと、そのメソッド(関数)を実行するという意味になってしまい、意図した通りの挙動になりません。

sample_list.sort(key=str.lower)の実行手順は次の通りです。

  1. ソート用データの生成
    • 比較用のデータを展開するため、"sample_list"の各要素がlowerメソッドによって小文字に変換されます
  2. 小文字に変換されたkeyの要素を比較して並び替えが行われます
    • 並び替えの比較は"key"が基準になります
  3. 並び替えの結果は、['A', 'a', 'b', 'B', 'c', 'C']になります。"key"はあくまでも比較用に展開されたものなので、出力される要素には影響ありません。
    • 比較対象の要素が同等な場合、元のリストの順序で格納されます。

str.lowerの"key"を指定すると、大文字・小文字の区別なく並び替えが行われました。このように、listの要素の並び替えの基準を調整したい時に"key"引数を指定します。

reverse()

reverse()メソッドは、リストの要素を逆順に並べ替えます。ソートは行いません。これは、元のlistを変更する、破壊的な更新になります。

sample_list = ['c', 'a', 'b', 'd']
sample_list.reverse()
print(sample_list)  # ['d', 'b', 'a', 'c']
スポンサーリンク