Python 入門

Python リスト操作:追加、削除、ソート

リストは Python における基礎的なデータ構造であり、項目の集合を格納・操作するために使用されます。
本章では、要素の追加、削除、およびソートといったリストを修正する基本操作について深く掘り下げます。

1. リストへの要素の追加

Python では、リストに要素を追加する方法が複数用意されています。どのメソッドを使用するかは、リストのどの位置に要素を追加したいのか、また、単一の要素を追加するのか複数の要素を追加するのかによって異なります。

1.1 append() メソッド

append() メソッドは、単一の要素をリストの末尾に追加します。これは、リストに要素を追加する際に最も頻繁に使用されるメソッドです。

# 例:リストの末尾に要素を追加する
my_list = [1, 2, 3]
my_list.append(4)
print(my_list)  # 出力: [1, 2, 3, 4]

# 文字列を追加
my_list = ["apple", "banana", "cherry"]
my_list.append("date")
print(my_list) # 出力: ['apple', 'banana', 'cherry', 'date']

# リストを追加(ネストされたリストが作成される)
my_list = [1, 2, 3]
my_list.append([4, 5])
print(my_list) # 出力: [1, 2, 3, [4, 5]]

1.2 insert() メソッド

insert() メソッドは、リストの指定したインデックス(位置)に要素を追加します。このメソッドは、挿入したい位置のインデックスと、挿入する要素自体の 2 つの引数を受け取ります。

# 例:指定したインデックスに要素を挿入する
my_list = [1, 2, 3]
my_list.insert(1, 4)  # インデックス 1 の位置に 4 を挿入
print(my_list)  # 出力: [1, 4, 2, 3]

# リストの先頭に挿入
my_list = ["apple", "banana", "cherry"]
my_list.insert(0, "date")
print(my_list) # 出力: ['date', 'apple', 'banana', 'cherry']

# リストの現在の長さを超える位置に挿入(append と同様の動作になる)
my_list = [1, 2, 3]
my_list.insert(10, 4)
print(my_list) # 出力: [1, 2, 3, 4]

1.3 extend() メソッド

extend() メソッドは、複数の要素をリストの末尾に一括で追加します。引数としてイテラブル(リスト、タプル、文字列など)を受け取り、その中の各要素を順番にリストへ追加します。

# 例:別のリストで現在のリストを拡張する
my_list = [1, 2, 3]
my_list.extend([4, 5, 6])
print(my_list)  # 出力: [1, 2, 3, 4, 5, 6]

# タプルで拡張
my_list = ["apple", "banana"]
my_list.extend(("cherry", "date"))
print(my_list) # 出力: ['apple', 'banana', 'cherry', 'date']

# 文字列で拡張(各文字が1つの要素として追加される)
my_list = [1, 2, 3]
my_list.extend("456")
print(my_list) # 出力: [1, 2, 3, '4', '5', '6']

1.4 + 演算子の使用

+ 演算子を使用してリストを結合し、あるリストの要素を別のリストに追加することもできます。この方法では新しいリストが生成され、元のリストは変更されません。

# 例:+ 演算子を使用してリストを結合する
list1 = [1, 2, 3]
list2 = [4, 5, 6]
new_list = list1 + list2
print(new_list)  # 出力: [1, 2, 3, 4, 5, 6]
print(list1) # 出力: [1, 2, 3] (list1 は変更されない)

# 異なるデータ型を組み合わせる(+ で結合するには型の整合性が必要)
list1 = [1, 2, "hello"]
list2 = [3.14, True]
new_list = list1 + list2
print(new_list) # 出力: [1, 2, 'hello', 3.14, True]

2. リストからの要素の削除

要素の追加と同様に、Python ではリストから要素を削除するための方法もいくつか提供されています。削除したい要素のインデックスがわかっているのか、あるいは値そのものがわかっているのかによって、最適な方法を選択します。

2.1 remove() メソッド

remove() メソッドは、リスト内で最初に見つかった指定値を削除します。もしリスト内にその値が存在しない場合は、ValueError が発生します。

# 例:値による要素の削除
my_list = [1, 2, 3, 2]
my_list.remove(2)  # 最初に出現する 2 を削除
print(my_list)  # 出力: [1, 3, 2]

# 文字列を削除
my_list = ["apple", "banana", "cherry", "banana"]
my_list.remove("banana")
print(my_list) # 出力: ['apple', 'cherry', 'banana']

# 要素が見つからない場合の ValueError 処理
my_list = [1, 2, 3]
try:
    my_list.remove(4)
except ValueError:
    print("リスト内に該当する要素が見つかりません") # 出力: リスト内に該当する要素が見つかりません

2.2 pop() メソッド

pop() メソッドは、指定したインデックスにある要素を削除し、その値を返します。インデックスを指定しない場合は、デフォルトでリストの最後の要素を削除して返します。

# 例:インデックスによる要素の削除
my_list = [1, 2, 3]
removed_element = my_list.pop(1)  # インデックス 1 の要素(2)を削除
print(my_list)  # 出力: [1, 3]
print(removed_element)  # 出力: 2

# 最後の要素を削除
my_list = ["apple", "banana", "cherry"]
removed_element = my_list.pop()
print(my_list) # 出力: ['apple', 'banana']
print(removed_element) # 出力: cherry

# インデックスが範囲外の場合の IndexError 処理
my_list = [1, 2, 3]
try:
    removed_element = my_list.pop(5)
except IndexError:
    print("インデックスが範囲外です") # 出力: インデックスが範囲外です

2.3 del 文

del 文は、リストから要素を削除するためのより汎用的な方法です。単一の要素だけでなく、スライスを用いた範囲指定での削除や、リストそのものの削除も可能です。

# 例:インデックスによる単一要素の削除
my_list = [1, 2, 3]
del my_list[1]  # インデックス 1 の要素(2)を削除
print(my_list)  # 出力: [1, 3]

# スライスによる範囲指定での削除
my_list = ["apple", "banana", "cherry", "date"]
del my_list[1:3] # インデックス 1 から 3 の手前(インデックス 2)までの要素を削除
print(my_list) # 出力: ['apple', 'date']

# リスト全体の削除
my_list = [1, 2, 3]
del my_list
# print(my_list)  # リストが既に存在しないため NameError が発生する

2.4 clear() メソッド

clear() メソッドは、リスト内のすべての要素を削除し、リストを空にします。

# 例:リストを空にする
my_list = [1, 2, 3]
my_list.clear()
print(my_list)  # 出力: []

3. リスト要素のソート

Python には、リストをソートするための主な方法として、sort() メソッドと sorted() 関数の 2 つがあります。これらの違いを理解することは非常に重要です。

3.1 sort() メソッド

sort() メソッドは、リストを破壊的(in place)にソートします。つまり、元のリスト自体が直接書き換えられ、戻り値として新しいリストを返すことはありません。

# 例:昇順にリストをソートする
my_list = [3, 1, 4, 1, 5, 9, 2, 6]
my_list.sort()
print(my_list)  # 出力: [1, 1, 2, 3, 4, 5, 6, 9]

# アルファベット順に文字列リストをソートする
my_list = ["banana", "apple", "cherry"]
my_list.sort()
print(my_list) # 出力: ['apple', 'banana', 'cherry']

# 降順にソート
my_list = [3, 1, 4, 1, 5, 9, 2, 6]
my_list.sort(reverse=True)
print(my_list)  # 出力: [9, 6, 5, 4, 3, 2, 1, 1]

# カスタム key 関数を使用したソート
my_list = ["banana", "Apple", "cherry"]
my_list.sort(key=str.lower) # 大文字小文字を区別せずにソート
print(my_list) # 出力: ['Apple', 'banana', 'cherry']

3.2 sorted() 関数

sorted() 関数は、リスト、タプル、文字列などの任意のイテラブルを受け取り、ソートされた新しいリストを返します。元のオブジェクトは変更されません(非破壊的)。

# 例:sorted() を使用したソート
my_list = [3, 1, 4, 1, 5, 9, 2, 6]
new_list = sorted(my_list)
print(my_list)  # 出力: [3, 1, 4, 1, 5, 9, 2, 6] (元のリストは維持される)
print(new_list)  # 出力: [1, 1, 2, 3, 4, 5, 6, 9]

# タプルをソート
my_tuple = (3, 1, 4, 1, 5)
new_list = sorted(my_tuple)
print(my_tuple) # 出力: (3, 1, 4, 1, 5)
print(new_list) # 出力: [1, 1, 3, 4, 5]

# 文字列をソート(文字のリストが返される)
my_string = "banana"
new_list = sorted(my_string)
print(my_string) # 出力: banana
print(new_list) # 出力: ['a', 'a', 'a', 'b', 'n', 'n']

# 降順にソート
my_list = [3, 1, 4, 1, 5, 9, 2, 6]
new_list = sorted(my_list, reverse=True)
print(new_list)  # 出力: [9, 6, 5, 4, 3, 2, 1, 1]

# カスタム key 関数を使用したソート
my_list = ["banana", "Apple", "cherry"]
new_list = sorted(my_list, key=str.lower)
print(new_list) # 出力: ['Apple', 'banana', 'cherry']

3.3 ソートにおける Key 関数

sort()sorted() のどちらも、オプションで key 引数を受け取ります。この引数には関数を指定し、リスト内の各要素からソートの基準となる値を抽出します。これは複雑なオブジェクトをソートする場合や、特定の属性に基づいて並び替えたい場合に非常に強力です。

# 例:タプルの2番目の要素に基づいてソートする
my_list = [(1, 'z'), (2, 'a'), (3, 'b')]
my_list.sort(key=lambda item: item[1])  # 各タプルのインデックス 1 の要素でソート
print(my_list)  # 出力: [(2, 'a'), (3, 'b'), (1, 'z')]

# 特定のキーに基づいて辞書のリストをソートする
my_list = [{'name': 'Alice', 'age': 30}, {'name': 'Bob', 'age': 25}, {'name': 'Charlie', 'age': 35}]
new_list = sorted(my_list, key=lambda item: item['age']) # 'age' キーの値でソート
print(new_list) # 出力: [{'name': 'Bob', 'age': 25}, {'name': 'Alice', 'age': 30}, {'name': 'Charlie', 'age': 35}]