Python × 入門 | #19 タプルとセットを使おう

0-18では文字列メソッドを学びました。今回はリストに似ているが性質の異なるデータ構造、タプルとセットを学びます。

タプルとセット

まずはPycoBlocksを開こう

下のPycoBlocksで直接作業するか、別タブで開き、生成されるPythonコードを見ながら進めてください。

変更 重複 順序 用途
list可能ありあり変更が必要なデータ
tuple不可ありあり変更してはいけないデータ
set可能なしなし重複排除・集合演算
frozenset不可なしなし不変のセット

ステップ1:タプル(tuple)を作って使う

タプルは () で作るリストの仲間です。リストと違い、作成後に要素を変更できません。座標や RGB 値など、「意味のあるセットとして固定したいデータ」に向いています。

タプルを作るブロック例
# タプルの作成
point = (3, 7)
color = (255, 128, 0)

print(point[0])    # 3(インデックスアクセスはリストと同じ)
print(color[1])    # 128

# アンパック(多重代入)
x, y = point
print(x, y)        # 3 7

# タプルは変更できない
# point[0] = 10  → TypeError が発生する

# 要素数1のタプルにはカンマが必要
single = (42,)
print(type(single))  # <class 'tuple'>

ステップ2:セット(set)で重複を排除する

セットは重複した要素を自動的に除去します。また、和集合・積集合・差集合などの集合演算が使えるのが特徴です。

セットのブロック例
# セットの作成
fruits = {"apple", "banana", "apple", "cherry"}
print(fruits)   # {'banana', 'cherry', 'apple'}(重複は消える)

# 要素の追加・削除
fruits.add("grape")
fruits.discard("banana")
print(fruits)

# リストの重複を取り除く
scores = [80, 90, 80, 70, 90, 100]
unique = list(set(scores))
print(unique)   # [80, 90, 70, 100](順序は不定)

# 集合演算
a = {1, 2, 3, 4}
b = {3, 4, 5, 6}
print(a | b)   # 和集合: {1, 2, 3, 4, 5, 6}
print(a & b)   # 積集合: {3, 4}
print(a - b)   # 差集合: {1, 2}

ステップ3:frozenset(不変のセット)

frozenset はセットを変更不可にしたものです。辞書のキーに使えたり、別のセットの要素にできるなど、「変わってはいけない集合」が必要なときに使います。

frozenset のブロック例
vowels = frozenset("aeiou")
print(vowels)            # frozenset({'a', 'e', 'i', 'o', 'u'})
print("a" in vowels)     # True

# frozenset は変更できない
# vowels.add("y")  → AttributeError

# frozenset を辞書のキーに使う例
pairs = {frozenset({1, 2}): "pair A", frozenset({3, 4}): "pair B"}
print(pairs[frozenset({1, 2})])   # pair A

コーディングモードで書いてみよう

タプル・セットカテゴリのブロックを使うか、コーディングモードで直接書くことができます。

# 複数の戻り値をタプルで返す
def min_max(lst):
    return min(lst), max(lst)

lo, hi = min_max([5, 2, 9, 1, 7])
print(lo, hi)   # 1 9

# 2つのリストで共通する要素を求める
list_a = [1, 2, 3, 4, 5]
list_b = [3, 4, 5, 6, 7]
common = set(list_a) & set(list_b)
print(common)   # {3, 4, 5}

演習課題

課題19-1:座標をタプルで扱う

タプル (10, 20) を変数 pos に代入し、アンパックで x, y に分解して表示するプログラムを書いてみましょう。

▶ 模範解答と解説を見る

ブロックの組み合わせ例:

タプルをアンパックするブロック例
pos = (10, 20)
x, y = pos
print("x =", x)
print("y =", y)

解説: タプルのアンパックは複数の変数に一度に値を代入できる便利な構文です。関数の戻り値にも多用します。

課題19-2:重複を取り除く

リスト [3, 1, 4, 1, 5, 9, 2, 6, 5, 3] から重複を取り除き、昇順に並べて表示するプログラムを書いてみましょう。

▶ 模範解答と解説を見る

ブロックの組み合わせ例:

sorted(set())で重複削除+昇順にするブロック例
nums = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3]
unique_sorted = sorted(set(nums))
print(unique_sorted)   # [1, 2, 3, 4, 5, 6, 9]

解説: set で重複を除去してから sorted で並べると、一行で完結します。セットは順序を保証しないため、並べ替えが必要な場合は sorted を使います。

課題19-3:2つのクラスの共通生徒を求める

クラスA の生徒名リスト ["田中", "鈴木", "山田", "佐藤"] とクラスB の生徒名リスト ["山田", "伊藤", "田中", "中村"] があるとき、両クラスに在籍している生徒の名前を求めてみましょう。

▶ 模範解答と解説を見る

ブロックの組み合わせ例:

積集合(&)で共通の生徒を求めるブロック例
class_a = ["田中", "鈴木", "山田", "佐藤"]
class_b = ["山田", "伊藤", "田中", "中村"]
common = set(class_a) & set(class_b)
print("両クラスにいる生徒:", common)

解説: 積集合 & を使うと、両方のセットに含まれる要素だけが残ります。リストをセットに変換してから演算するのが基本パターンです。

課題19-4:どちらかにしかいない生徒を求める

課題19-3 のリストを使い、片方のクラスにしかいない生徒全員の名前を求めてみましょう(対称差集合)。

▶ 模範解答と解説を見る

ブロックの組み合わせ例:

対称差(^)でどちらか一方の生徒を求めるブロック例
class_a = {"田中", "鈴木", "山田", "佐藤"}
class_b = {"山田", "伊藤", "田中", "中村"}
only_one = class_a ^ class_b
print("片方のクラスにしかいない生徒:", only_one)

解説: ^ 演算子は対称差集合(どちらか一方にだけ含まれる要素の集合)を求めます。- は差集合(一方にあって他方にない要素)と区別しましょう。

課題19-5:タプルのリストをソートする

点数と名前のタプルのリスト [("田中", 85), ("鈴木", 92), ("山田", 78)] を点数の降順に並べて表示するプログラムを書いてみましょう。

▶ 模範解答と解説を見る

ブロックの組み合わせ例:

タプルリストを成績順に並べるブロック例
students = [("田中", 85), ("鈴木", 92), ("山田", 78)]
ranked = sorted(students, key=lambda s: s[1], reverse=True)
for name, score in ranked:
    print(name, score)

解説: sortedkey 引数にラムダ式を渡すと、タプルの任意の要素でソートできます。reverse=True で降順になります。

まとめ

  • タプルは変更不可のリスト。座標・RGB など「固定したい値の組」に使います
  • アンパックで複数変数に一度に代入できます
  • セットは重複なし・順序なし。重複排除と集合演算が強み
  • |(和)、&(積)、-(差)、^(対称差)で集合演算できます
  • frozenset は変更不可のセット。辞書のキーにも使えます

次は「リスト内包表記」を学びます。→ Python × 入門 | #20 リスト内包表記を使おう

PAGE TOP