[PR] 本記事にはプロモーションが含まれています。

【Python】リスト・タプル・セットの違い|カッコの書き方、追加・削除の操作、使い分けと注意点

Python

Pythonで複数のデータをまとめて扱うときによく使うのが、「リスト(list)」「タプル(tuple)」「セット(set)」です。書き方は []、()、{} とカッコが違うだけに見えますが、順番、重複、書き換えられるかどうかがそれぞれ違います。

C言語でいえば、リストは大きさを変えられる配列、タプルは const を付けた配列、セットはハッシュテーブルに近いものです。この記事では、3つの違いと、要素の追加・削除のやり方、つまずきやすい点をまとめます。

3つの違いの一覧

種類書き方順番同じ値の重複作ったあとの変更向いている使い方
リスト(list)[1, 2, 3]あるできるできる順番のあるデータを追加・削除しながら使う
タプル(tuple)(1, 2, 3)あるできるできない座標や設定値など、変えない組
セット(set){1, 2, 3}ないできないできる重複をなくす、含まれているかをよく調べる

セットには順番がないので、print したときの並び順も決まっていません。入れた順に表示されるとは限らないので、順番が大事なときはリストを使います。

カッコの書き方で間違えやすいところ

Python
empty_list = []        # 空のリスト
empty_tuple = ()       # 空のタプル
empty_set = set()      # 空のセット({} ではない)
empty_dict = {}        # {} だけだと、セットではなく辞書になる

one = (1,)             # 要素が1つのタプルは、最後にカンマが必要
not_tuple = (1)        # カンマがないと、ただの数値の 1

print(type(empty_dict))  # <class 'dict'>
print(type(one))         # <class 'tuple'>
print(type(not_tuple))   # <class 'int'>

タプルを作っているのは、実はカッコではなくカンマです。point = 10, 20 のようにカッコを省いても、タプルになります。

要素の追加と削除

リスト

Python
fruits = ["apple", "banana"]

fruits.append("cherry")        # 最後に1つ追加  → ['apple', 'banana', 'cherry']
fruits.insert(0, "melon")      # 0番目に入れる  → ['melon', 'apple', 'banana', 'cherry']
fruits.extend(["kiwi", "fig"]) # まとめて追加

fruits.remove("banana")        # 最初に見つかった "banana" を削除(なければ ValueError)
last = fruits.pop()            # 最後の要素を取り出して削除(pop(0) なら先頭)
fruits.clear()                 # すべて削除

タプル

タプルは作ったあとに変更できないので、append や remove のようなメソッドはありません。要素を足したいときは、新しいタプルを作ります。

Python
colors = ("red", "green")

# + でつなげて、新しいタプルを作る(元のタプルは変わらない)
more_colors = colors + ("blue",)
print(more_colors)  # ('red', 'green', 'blue')

# 何度も変えるなら、リストにしてから操作し、最後にタプルに戻す
temp = list(colors)
temp.remove("green")
colors2 = tuple(temp)
print(colors2)      # ('red',)

何度も追加や削除をするデータなら、最初からリストにしておくほうが自然です。

セット

Python
tags = {"python", "web"}

tags.add("server")             # 1つ追加(すでにあれば何も起きない)
tags.update(["linux", "web"])  # まとめて追加("web" は重複するので増えない)

tags.discard("java")           # 削除(なくてもエラーにならない)
tags.remove("linux")           # 削除(なければ KeyError)
some = tags.pop()              # どれか1つを取り出して削除(どれが出るかは決まっていない)

セットには順番がないので、tags[0] のように番号で取り出すことはできません。

つまずきやすいところ

タプルの要素は書き換えられない(TypeError)

Python
point = (1, 2, 3)
point[1] = 5  # TypeError: 'tuple' object does not support item assignment

ただし、タプルの中にリストが入っている場合、そのリストの中身は変えられます。タプルが守っているのは「どのオブジェクトを指しているか」だけで、指している先の中身までは守りません。

Python
record = ("taro", [80, 90])
record[1].append(70)   # エラーにならない
print(record)          # ('taro', [80, 90, 70])

C言語でいえば、ポインタ自体が const でも、指している先のデータは書き換えられるのに似ています。

セットで重複を消すと、順番が崩れる

リストの重複を消すのに set を使うと手軽ですが、順番は残りません。順番を残したいときは dict.fromkeys を使います。

Python
visits = ["tokyo", "osaka", "tokyo", "nagoya", "osaka"]

print(list(set(visits)))            # 重複は消えるが、順番は決まっていない
print(list(dict.fromkeys(visits)))  # ['tokyo', 'osaka', 'nagoya'](最初に出てきた順)

セットにはリストを入れられない

セットの要素は、中身が変わらないもの(ハッシュ化できるもの)である必要があります。数値や文字列、タプルは入れられますが、リストや辞書、セットは入れられません。

Python
ok = {1, "hello", (1, 2)}   # 数値・文字列・タプルはOK

# ng = {[1, 2], [3, 4]}    # TypeError: unhashable type: 'list'

# セットを入れたいときは、変更できない frozenset にする
groups = {frozenset({1, 2}), frozenset({3, 4})}

上の record のように、中にリストを含むタプルも、セットには入れられません。

「含まれているか」を調べる速さ

x in データ で値が含まれているかを調べるとき、リストとタプルは先頭から順に探すので、要素が多いほど時間がかかります。セットはハッシュテーブルで管理されているので、要素が多くてもほぼ一定の時間で調べられます。大きなデータで何度も「含まれているか」を調べるなら、セットにしておくと速くなります。

Python
allowed = {"admin", "editor", "viewer"}
print("editor" in allowed)  # True

セットの集合演算

セット同士は、記号で「両方にあるもの」「どちらかにあるもの」などを求められます。

Python
a = {1, 2, 3}
b = {2, 3, 4}

print(a | b)  # {1, 2, 3, 4}  和集合:どちらかにある
print(a & b)  # {2, 3}        積集合:両方にある
print(a - b)  # {1}           差集合:a にだけある
print(a ^ b)  # {1, 4}        どちらか一方だけにある

タプルの便利な使い方:分割代入

タプルは、関数から複数の値を返すときにも使われます。受け取る側では、それぞれの変数に分けて入れられます。

Python
def min_max(numbers):
    return min(numbers), max(numbers)  # カンマで区切るとタプルで返る

low, high = min_max([3, 8, 1, 5])
print(low, high)  # 1 8

TypeScriptにも同じような「タプル」があり、「タプル(Tuple)とは?」で紹介しています。

まとめ:どれを使うか

  • リスト []:順番が大事で、あとから追加や削除をするとき。迷ったらまずリスト
  • タプル ():座標や設定値など、変えない組。関数から複数の値を返すときや、辞書のキーにしたいとき
  • セット {}:重複をなくしたいとき、「含まれているか」を何度も調べるとき、集合演算をしたいとき。空のセットは set()

値を表示するときの書き方は、「f文字列(f-string)の使い方」で紹介しています。

ほかの開発・プログラミングの記事は、開発・プログラミングメモの目次から、テーマ別に探せます。

このブログは、にほんブログ村と人気ブログランキングに参加しています。記事が役に立ったら、下のランキングのバナーのどれかを押して応援してもらえると励みになります。

ブログランキング・にほんブログ村へにほんブログ村

サーバー構築・運用ランキング プログラムランキング

Python
watasoftdevをフォローする

コメント