基礎

Pythonのリスト(list):メソッド、スライス、ソート、append、タプルと集合

更新日: · Skillaria.Top

Pythonのリスト(list)は、角かっこで囲んで書く、順序があり変更できる値の並びです。例えば [250, 1200, 99] のように書きます。要素はappendで追加し、挿入、削除、スライスによる取り出し、並べ替えができます。sortメソッドはリストをその場で並べ替えてNoneを返し、sorted関数は新しい並べ替え済みのリストを返します。

Pythonのリスト(list)は、角かっこで囲んだ値の並びで、中身を変更できます。末尾に要素を追加し、途中に挿入し、削除し、並べ替えられます。言語の中で最もよく使われるコレクションで、ファイルの行、月の支出、APIの応答など、多くのデータがリストとして扱われます。ここではPythonのリストを一通り見ていきます。作成、メソッド、スライス、並べ替え、リスト内包表記、コピーを扱い、最後にタプルと集合を紹介します。

Pythonのリストとは

リストは要素を指定した順序で保持し、0から始まる番号(インデックス)で要素にアクセスします。1つのリストに異なる型の値を入れることもできますが、実際には同じ種類のデータをまとめて扱うことが多いです。

amounts = [250, 1200, 99]
print(amounts[0])     # 250 — 最初の要素
print(amounts[-1])    # 99 — 最後の要素
amounts[1] = 1300     # リストは変更できる
print(len(amounts))   # 3 — リストの長さ

リストの長さは len() 関数で求めます。存在しないインデックスを指定すると、IndexError: list index out of range が発生します。

リストの作成

empty = []                       # 空のリスト
also_empty = list()              # list 関数で作成しても同じ
nums = [1, 2, 3]
chars = list("abc")              # ['a', 'b', 'c']
digits = list(range(5))          # [0, 1, 2, 3, 4]
zeros = [0] * 4                  # [0, 0, 0, 0]

list() 関数は、文字列、range、集合、辞書のキーなど、繰り返し可能なオブジェクトをリストに変換します。

appendとその他のリストメソッド

append は、要素を1つ末尾に追加するメソッドです。Pythonで最もよく使われるメソッドの1つです。リストをその場で変更し、戻り値は None です。

amounts = [250, 1200]
amounts.append(450)          # [250, 1200, 450]
amounts.extend([10, 20])     # [250, 1200, 450, 10, 20]
amounts.insert(0, 5)         # [5, 250, 1200, 450, 10, 20]
amounts.remove(1200)         # 最初の値 1200 を削除
last = amounts.pop()         # 20 — 最後の要素を削除して返す

よくあるミスは、a.append([10, 20]) と書くことです。これは2つの数字ではなく、1つの要素(入れ子のリスト)を追加します。複数の要素を追加するには extend を使います。

メソッド役割
append(x)x を末尾に追加
extend(iter)並びの全要素を追加
insert(i, x)インデックス i の前に x を挿入
remove(x)最初に現れる x を削除(なければ ValueError)
pop(i=-1)インデックス i の要素を削除して返す
index(x)x が最初に現れる位置
count(x)x の出現回数
sort()その場で並べ替え
reverse()その場で逆順にする
copy()浅いコピーを作る
clear()リストを空にする

インデックスや範囲を指定して削除するには del 文も使えます。例:del a[0]、del a[1:3]。リストに使える組み込み関数には、len、sum、min、max、sorted、reversed、enumerate、zip があります。

Pythonのスライス

スライスは a[start:stop:step] の形でリストの一部を取り出します。start は含まれ、stop は含まれず、step ごとに取り出します。どの部分も省略できます。スライスは必ず新しいリストを返します。

a = [0, 1, 2, 3, 4, 5]
print(a[1:4])     # [1, 2, 3]
print(a[:2])      # [0, 1] — 最初の2つ
print(a[-2:])     # [4, 5] — 最後の2つ
print(a[::2])     # [0, 2, 4] — 1つおき
print(a[::-1])    # [5, 4, 3, 2, 1, 0] — 逆順
print(a[:])       # リスト全体のコピー

インデックスと違い、リストの範囲外を指定したスライスはエラーになりません。a[10:20] は単に [] を返します。スライスに値を代入して、リストの一部を置き換えることもできます。例:a[1:3] = ["x", "y", "z"]。

文字列のスライス

スライスは、文字列やタプルなど、どの並びに対しても同じように使えます。

s = "Python 3.15"
print(s[:6])      # Python
print(s[-4:])     # 3.15
print(s[::-1])    # 51.3 nohtyP

文字列はスライスで変更できません。文字列は変更不可能で、スライスは新しい文字列を作るだけです。

リストの並べ替え:sortとsorted

ここは初心者が最も混乱しやすい部分です。sort メソッドはリスト自体の要素を並べ替え、戻り値は None です。一方、sorted 関数は元のリストに触れず、並べ替えた新しいリストを返します。

amounts = [250, 1200, 99]
amounts.append(450)
print(sorted(amounts))     # [99, 250, 450, 1200] — 新しいコピー
print(amounts)             # [250, 1200, 99, 450] — 元のリストはそのまま

result = amounts.sort()    # その場で並べ替え
print(result, amounts)     # None [99, 250, 450, 1200]

ここから「なぜ None になるのか」という典型的な問題が生まれます。a = a.sort() と書くと、リストが None で上書きされてしまいます。a.sort() と書くか、a = sorted(a) と書きましょう。

キーと逆順

どちらの方法も key と reverse という引数を受け取ります。key は、要素を比較するための値を計算する関数です。

words = ["coffee", "Taxi", "subscription"]
print(sorted(words, key=len))               # ['Taxi', 'coffee', 'subscription']
print(sorted(words, key=str.lower))         # 大文字・小文字を区別せずに並べ替え
print(sorted([3, 1, 2], reverse=True))      # [3, 2, 1]

expenses = [("食費", 650), ("映画", 120), ("タクシー", 300)]
expenses.sort(key=lambda e: e[1])           # 金額順

Pythonのソートは安定しています。同じキーを持つ要素は、元の順序を保ちます。また、sorted は文字列、辞書、集合など、どの並びでも使えますが、sort メソッドはリストだけのメソッドです。

リストを逆順にする

方法は3つあり、動作が異なります。

  • a.reverse() ― その場で逆順にし、戻り値は None。
  • a[::-1] ― 逆順になった新しいリストを作る。
  • reversed(a) ― 遅延評価のイテレータ。ループで便利です。例:for x in reversed(a):。

リストのループ

items = ["コーヒー", "電車", "映画"]
for item in items:
    print(item)

for i, item in enumerate(items, start=1):
    print(i, item)          # 1 コーヒー、2 電車、3 映画

print("映画" in items)      # True — 要素が含まれるかの確認

ループしているリストから要素を削除しないでください。一部の要素が飛ばされてしまいます。リスト内包表記で新しいリストを作るか、コピー a[:] をループしましょう。

リスト内包表記

リスト内包表記(list comprehension)は、式、ループ、省略可能な条件を1行に書いて新しいリストを作ります。

squares = [n * n for n in range(6)]          # [0, 1, 4, 9, 16, 25]
big = [a for a in [250, 1200, 99] if a > 200]  # [250, 1200]
names = [s.strip().title() for s in [" anna ", "oleg"]]

リスト内包表記は、append を使うループより速く、読みやすいことが多いです。ただし、処理が1行で分かりやすく書けないなら、普通のループの方が良い選択です。

リストの結合、連結、差分

a = [1, 2, 3]
b = [3, 4]
print(a + b)       # [1, 2, 3, 3, 4] — 新しいリスト
a += b             # a.extend(b) と同じ
print([*a, *b])    # アンパックで新しいリストを作る

リストに - 演算子はありません。1つのリストから別のリストの要素を取り除きたいときは、内包表記を使います。例:[x for x in a if x not in set(b)]。2つのリストの共通部分は、集合を使うと簡単に求められます。例:set(a) & set(b)(順序と重複は失われます)。

入れ子のリストと二次元リスト

リストのリストは、表や行列を保持する簡単な方法です。

matrix = [[1, 2, 3], [4, 5, 6]]
print(matrix[1][2])     # 6
grid = [[0] * 3 for _ in range(2)]   # 正しい書き方
bad = [[0] * 3] * 2                  # 落とし穴:同じリストへの参照が2つ
bad[0][0] = 9
print(bad)              # [[9, 0, 0], [9, 0, 0]]

リストのアンパック

first, second, third = [10, 20, 30]
head, *rest = [1, 2, 3, 4]      # head=1, rest=[2, 3, 4]
print(*["a", "b"], sep=", ")    # a, b — 角かっこなしで表示

変数の数がリストの長さと合わないと ValueError が出ます。そのようなときは、アスタリスクが役立ちます。

リストのコピー

b = a はリストをコピーしません。同じオブジェクトに2つ目の名前を付けるだけです。そのため、b を変更すると a も変わります。独立したコピーを作るには、明示的に a.copy()、list(a)、または a[:] を使います。入れ子のデータでは、これだけでは不十分です。内側のリストは共有されたままになるため、copy.deepcopy(a) が必要です。

import copy
a = [[1, 2], [3]]
b = a.copy()
b[0].append(99)
print(a)                 # [[1, 2, 99], [3]] — 内側のリストは共有されている
c = copy.deepcopy(a)     # 完全に独立したコピー

タプル:変更できないリスト

タプル(tuple)はリストに似ていますが、作成後は変更できません。これは読み手に対する明確なメッセージです。固定の項目を持つ1つのレコードであり、増えていく集まりではない、ということです。タプルは簡単にアンパックでき、関数が複数の値を返すときにもよく使われます。

expense = (250, "コーヒー")
amount, item = expense
expense[0] = 300
# TypeError: 'tuple' object does not support item assignment

変更できない値だけからなるタプルはハッシュ可能なので、辞書のキーに使えます。要素が1つだけのタプルは、カンマを付けて書きます。例:(5,)。

集合:一意の値だけ

集合(set)は一意な値だけを保持し、順序は覚えません。重複を取り除くことや「その要素があるか」の確認が最も速くできる方法で、和集合、積集合、差集合も扱えます。

jan = {"食費", "タクシー", "映画"}
feb = {"食費", "サブスク"}
print(jan & feb)    # {'食費'}
print(feb - jan)    # {'サブスク'}
unique = list(dict.fromkeys([3, 1, 3, 2]))   # [3, 1, 2] — 重複を除き、順序を保持
empty = set()       # {} は空の dict です!

どのコレクションを選ぶか

用途コレクション
順序があり、変更もするlist
項目が固定のレコードtuple
キーで検索するdict
一意性、「含まれるか」の確認set
変更できない設定frozendict(Python 3.15)

x in list は要素を先頭から順に調べますが、x in set はほぼ一瞬で結果が出ます。大きなリストへの「含まれるか」の確認をループの中で何度も行うなら、集合に変換しましょう。

まとめ

Pythonのリストは、順序があり変更できるコレクションです。append と extend で追加し、pop と remove で削除します。スライス a[start:stop:step] で一部を取り出し、sort はその場で並べ替えて None を返し、sorted は新しいリストを返します。コピーは明示的に作り、固定のレコードにはタプル、一意な値には集合を使いましょう。リスト、タプル、辞書、集合は、講座「Python 3.15:初心者からプロへ」の実践的な講義で扱っています。

よくある質問

Pythonのリストと配列の違いは何ですか?

Pythonには他の言語のような組み込みの配列はありません。その役割はリストが担い、異なる型の値を混在させることもできます。数値だけをコンパクトに扱いたいときは、標準の array モジュールやNumPyを使います。

リストの中で要素の位置を調べるにはどうしますか?

a.index(x) は最初に現れる位置を返します。要素がないと ValueError になるので、呼び出す前に x in a で確認しましょう。

順序を保ったままリストの重複を削除するにはどうしますか?

list(dict.fromkeys(a)) を使います。辞書はキーを一意に保ち、挿入順を覚えています。list(set(a)) でも重複は消えますが、順序は保たれません。

文字列のリストを1つの文字列にするにはどうしますか?

文字列のメソッド join を使います。例:", ".join(["a", "b", "c"]) は "a, b, c" になります。すべての要素が文字列である必要があるので、数値は先に map(str, a) で変換します。

リストに異なる型の要素を入れてもよいですか?

はい。数字、文字列、別のリスト、任意のオブジェクトを同時に入れられます。ただし、key 引数なしで並べ替えると、数字と文字列の比較は TypeError になるため、通常は避けましょう。

動画でこのテーマを学ぶ

このテーマはコース「Python 3.15: от новичка до профи」で実践とともに詳しく解説しています。

コースへ