ステップ9:セットとブール型

🎲 ステップ9: セットとブール型

集合とTrue/Falseを学ぼう

前回はタプルと辞書を学びました。今回は、重複を許さない「セット」と、真偽を表す「ブール型」を学びます。

📖 このステップで学ぶこと

・セット(集合)とは何か、特徴と使い方

・セットの追加・削除・存在確認

・集合演算(和集合・積集合・差集合)

・ブール型(True/False)とは何か

・論理演算子(and, or, not)

・None型の理解と使い方

・データ型の変換

📝 1. セット(set)とは何か?

まず、セットとは何か、なぜ必要なのかを理解しましょう。

🔰 セットのイメージ

セット(集合)は、数学の「集合」と同じ考え方です。

💡 セットのイメージ

セットは「重複を許さない」データの集まりです。

例えば、クラスの出席番号を管理する場合、同じ番号が2回入ることはありませんよね。

セットはそのような「ユニーク(一意)な値の集まり」を管理するのに適しています。

📘 リスト・タプル・セットの比較

特徴 リスト タプル セット
記号 [ ] ( ) { }
重複 許可する 許可する 許可しない
順序 あり あり なし
インデックス 使える 使える 使えない
変更 できる できない できる
検索速度 遅い 遅い 非常に速い

💡 セットを使う場面

重複を削除したい時:リストから重複を取り除く

高速に検索したい時:大量のデータから素早く探す

集合演算をしたい時:共通要素を見つける、差分を調べるなど

📝 セットの作り方

セットは波カッコ {} で囲んで作ります。

コード:セットの基本的な作り方

# 文字列のセット
fruits = {"りんご", "バナナ", "オレンジ"}
print(fruits)
print(type(fruits))

実行結果

{'オレンジ', 'バナナ', 'りんご'}
<class 'set'>

※セットは順序がないため、表示される順番は毎回異なる可能性があります

📝 セットは重複を許さない

セットの最大の特徴は「重複を許さない」ことです。同じ値を入れても、自動的に1つになります。

コード:重複は自動的に削除される

# 重複する値を含むセットを作る
numbers = {1, 2, 3, 2, 1, 4, 3, 5, 1}
print(numbers)

実行結果

{1, 2, 3, 4, 5}

1、2、3が複数回入っていましたが、自動的に1つずつになりました。

⚠️ 空のセットの作り方に注意!

空のセットを作る時は set() を使います。{} だと辞書になってしまいます。

❌ よくある間違い

# これは辞書になる!
empty = {}
print(type(empty))  # <class 'dict'>

# 空のセットはset()で作る
empty_set = set()
print(type(empty_set))  # <class 'set'>

実行結果

<class 'dict'>
<class 'set'>

⚠️ 覚えておこう

{} → 空の辞書(dictionary)

set() → 空のセット(set)

{1, 2, 3} → 要素があればセット

📝 リストからセットを作る

既存のリストをセットに変換することもできます。これは重複削除に便利です。

コード:リストをセットに変換

# リストを用意
my_list = [1, 2, 3, 2, 4, 1, 5]
print(f"元のリスト: {my_list}")

# set()でセットに変換(重複が削除される)
my_set = set(my_list)
print(f"セットに変換: {my_set}")

実行結果

元のリスト: [1, 2, 3, 2, 4, 1, 5]
セットに変換: {1, 2, 3, 4, 5}

➕ 2. セットの操作

セットに要素を追加・削除する方法を学びましょう。

📘 セットの操作メソッド一覧

📌 追加と削除のメソッド

メソッド 機能 備考
add(要素) 1つの要素を追加 既にあれば何も起きない
update(リスト等) 複数の要素を追加 リストやセットを渡せる
remove(要素) 要素を削除 なければエラー
discard(要素) 要素を削除 なくてもエラーにならない
pop() ランダムに1つ削除 削除した値を返す
clear() 全要素を削除 空のセットになる

📝 add()で要素を追加

add()メソッドは、セットに1つの要素を追加します。

コード:add()で追加

fruits = {"りんご", "バナナ"}
print(f"最初: {fruits}")

# add()で1つ追加
fruits.add("オレンジ")
print(f"追加後: {fruits}")

# 既に存在する要素を追加しても変化なし
fruits.add("りんご")
print(f"りんご追加後: {fruits}")

実行結果

最初: {'バナナ', 'りんご'}
追加後: {'バナナ', 'オレンジ', 'りんご'}
りんご追加後: {'バナナ', 'オレンジ', 'りんご'}

「りんご」は既に存在するため、追加しても変化がありません。

📝 update()で複数の要素を追加

update()メソッドは、複数の要素をまとめて追加します。

コード:update()で複数追加

fruits = {"りんご", "バナナ"}
print(f"最初: {fruits}")

# update()でリストの要素を追加
fruits.update(["オレンジ", "ぶどう", "メロン"])
print(f"追加後: {fruits}")

実行結果

最初: {'バナナ', 'りんご'}
追加後: {'バナナ', 'オレンジ', 'メロン', 'ぶどう', 'りんご'}

💡 add()とupdate()の違い

add() → 1つの要素を追加

update() → 複数の要素をまとめて追加(リストやセットを渡す)

📝 remove()とdiscard()で削除

要素を削除する方法は2つあり、エラーの扱いが異なります。

コード:remove()で削除

fruits = {"りんご", "バナナ", "オレンジ"}
print(f"最初: {fruits}")

# remove()で削除(要素がないとエラー)
fruits.remove("バナナ")
print(f"削除後: {fruits}")

# 存在しない要素を削除しようとするとエラー
# fruits.remove("メロン")  # KeyError!

実行結果

最初: {'オレンジ', 'バナナ', 'りんご'}
削除後: {'オレンジ', 'りんご'}

コード:discard()で削除(安全)

fruits = {"りんご", "バナナ", "オレンジ"}
print(f"最初: {fruits}")

# discard()で削除(要素がなくてもエラーにならない)
fruits.discard("バナナ")
print(f"削除後: {fruits}")

# 存在しない要素を削除してもエラーにならない
fruits.discard("メロン")
print(f"メロン削除後: {fruits}")

実行結果

最初: {'オレンジ', 'バナナ', 'りんご'}
削除後: {'オレンジ', 'りんご'}
メロン削除後: {'オレンジ', 'りんご'}

📌 remove()とdiscard()の比較

メソッド 要素が存在する 要素が存在しない
remove() 削除される エラー(KeyError)
discard() 削除される 何も起きない(安全)

要素があるか不明な場合は discard() を使うと安全です。

📝 pop()とclear()

コード:pop()とclear()

fruits = {"りんご", "バナナ", "オレンジ", "ぶどう"}
print(f"最初: {fruits}")

# pop() - ランダムに1つ削除して、その値を返す
removed = fruits.pop()
print(f"削除された要素: {removed}")
print(f"pop後: {fruits}")

# clear() - 全要素を削除
fruits.clear()
print(f"clear後: {fruits}")

実行結果

最初: {'オレンジ', 'バナナ', 'ぶどう', 'りんご'}
削除された要素: オレンジ
pop後: {'バナナ', 'ぶどう', 'りんご'}
clear後: set()

※pop()で削除される要素は実行するたびに異なる可能性があります

📝 要素の存在確認(in演算子)

セットに特定の要素が含まれているかを in 演算子で確認できます。

コード:in演算子で存在確認

fruits = {"りんご", "バナナ", "オレンジ"}

# in演算子で存在確認
print("りんご" in fruits)  # True
print("メロン" in fruits)  # False

# if文と組み合わせる
if "バナナ" in fruits:
    print("バナナがあります!")
else:
    print("バナナはありません")

# len()で要素数を取得
print(f"要素数: {len(fruits)}")

実行結果

True
False
バナナがあります!
要素数: 3

💡 セットの検索は非常に高速

セットの in 演算子による検索は、リストよりもはるかに高速です。

大量のデータから検索する場合は、セットを使うことで処理時間を大幅に短縮できます。

🔄 3. セットの集合演算

セットの強力な機能は「集合演算」です。数学の集合と同じ計算ができます。

🔰 集合演算とは?

💡 集合演算のイメージ

2つのグループがあった時、以下のような操作ができます:

和集合:両方のグループの全メンバーを合わせる

積集合:両方のグループに共通するメンバーを見つける

差集合:一方にだけいるメンバーを見つける

📘 集合演算の一覧

演算 演算子 メソッド 意味
和集合 | union() 両方の全要素
積集合 & intersection() 両方に共通する要素
差集合 difference() 一方にだけある要素
対称差集合 ^ symmetric_difference() どちらか一方にだけある要素

📝 和集合(Union)- 全部合わせる

2つのセットの全ての要素を合わせた新しいセットを作ります。

コード:和集合

# 2つのセットを用意
set1 = {1, 2, 3, 4}
set2 = {3, 4, 5, 6}

print(f"set1: {set1}")
print(f"set2: {set2}")

# | 演算子で和集合
union_result = set1 | set2
print(f"和集合(|): {union_result}")

# union()メソッドでも同じ結果
union_result2 = set1.union(set2)
print(f"和集合(union): {union_result2}")

実行結果

set1: {1, 2, 3, 4}
set2: {3, 4, 5, 6}
和集合(|): {1, 2, 3, 4, 5, 6}
和集合(union): {1, 2, 3, 4, 5, 6}

💡 和集合のイメージ

set1の{1,2,3,4}とset2の{3,4,5,6}を全部合わせます。

3と4は両方にありますが、セットなので重複は1つになります。

結果:{1, 2, 3, 4, 5, 6}

📝 積集合(Intersection)- 共通要素を見つける

2つのセットに共通する要素だけを取り出します。

コード:積集合

set1 = {1, 2, 3, 4}
set2 = {3, 4, 5, 6}

print(f"set1: {set1}")
print(f"set2: {set2}")

# & 演算子で積集合
intersection_result = set1 & set2
print(f"積集合(&): {intersection_result}")

# intersection()メソッドでも同じ結果
intersection_result2 = set1.intersection(set2)
print(f"積集合(intersection): {intersection_result2}")

実行結果

set1: {1, 2, 3, 4}
set2: {3, 4, 5, 6}
積集合(&): {3, 4}
積集合(intersection): {3, 4}

💡 積集合のイメージ

set1とset2の両方に入っている要素だけを取り出します。

3と4は両方のセットに含まれています。

結果:{3, 4}

📝 差集合(Difference)- 片方だけの要素

一方のセットにあって、もう一方にない要素を取り出します。

コード:差集合

set1 = {1, 2, 3, 4}
set2 = {3, 4, 5, 6}

print(f"set1: {set1}")
print(f"set2: {set2}")

# set1 - set2:set1にあってset2にないもの
diff1 = set1 - set2
print(f"set1 - set2: {diff1}")

# set2 - set1:set2にあってset1にないもの
diff2 = set2 - set1
print(f"set2 - set1: {diff2}")

実行結果

set1: {1, 2, 3, 4}
set2: {3, 4, 5, 6}
set1 - set2: {1, 2}
set2 - set1: {5, 6}

💡 差集合のイメージ

set1 - set2:set1から、set2と共通する要素を引く

 → {1, 2, 3, 4} から 3, 4 を引いて {1, 2}

set2 - set1:set2から、set1と共通する要素を引く

 → {3, 4, 5, 6} から 3, 4 を引いて {5, 6}

⚠️ 注意:順番で結果が変わる

差集合は set1 - set2set2 - set1 で結果が異なります。

「どちらから引くか」によって結果が変わることに注意しましょう。

📝 対称差集合(Symmetric Difference)

どちらか一方にだけ存在する要素を取り出します。共通要素は除外されます。

コード:対称差集合

set1 = {1, 2, 3, 4}
set2 = {3, 4, 5, 6}

print(f"set1: {set1}")
print(f"set2: {set2}")

# ^ 演算子で対称差集合
symmetric_diff = set1 ^ set2
print(f"対称差集合(^): {symmetric_diff}")

実行結果

set1: {1, 2, 3, 4}
set2: {3, 4, 5, 6}
対称差集合(^): {1, 2, 5, 6}

💡 対称差集合のイメージ

「どちらか一方にだけある」要素を集めます。

共通の3, 4は除外され、set1だけの1, 2とset2だけの5, 6が残ります。

結果:{1, 2, 5, 6}

🎯 4. セットの実用例

セットが実際のプログラムでどのように使われるか、具体例を見てみましょう。

例1: リストから重複を削除する

セットの最も一般的な使い方は、重複データの削除です。

コード:重複削除

# 重複を含むリスト
numbers = [1, 2, 3, 2, 4, 1, 5, 3, 6, 2]
print(f"元のリスト: {numbers}")
print(f"要素数: {len(numbers)}")

# セットに変換して重複を削除
unique_set = set(numbers)
print(f"重複削除(セット): {unique_set}")

# リストに戻す
unique_list = list(unique_set)
print(f"重複削除(リスト): {unique_list}")

# ソートも一緒にする
sorted_unique = sorted(set(numbers))
print(f"重複削除&ソート: {sorted_unique}")
print(f"要素数: {len(sorted_unique)}")

実行結果

元のリスト: [1, 2, 3, 2, 4, 1, 5, 3, 6, 2]
要素数: 10
重複削除(セット): {1, 2, 3, 4, 5, 6}
重複削除(リスト): [1, 2, 3, 4, 5, 6]
重複削除&ソート: [1, 2, 3, 4, 5, 6]
要素数: 6

💡 コードの解説

set(numbers) → リストをセットに変換(重複が自動削除)

list(unique_set) → セットをリストに戻す

sorted(set(numbers)) → 重複削除してソートまで一度に行う

例2: 共通の趣味を見つける

積集合を使って、2人の共通点を見つけます。

コード:共通の趣味を見つける

# 2人の趣味
person_a = {"読書", "映画", "音楽", "料理"}
person_b = {"映画", "スポーツ", "音楽", "旅行"}

print(f"Aさんの趣味: {person_a}")
print(f"Bさんの趣味: {person_b}")

# 共通の趣味(積集合)
common = person_a & person_b
print(f"\n共通の趣味: {common}")

# Aさんだけの趣味(差集合)
only_a = person_a - person_b
print(f"Aさんだけの趣味: {only_a}")

# Bさんだけの趣味(差集合)
only_b = person_b - person_a
print(f"Bさんだけの趣味: {only_b}")

# 全ての趣味(和集合)
all_hobbies = person_a | person_b
print(f"全ての趣味: {all_hobbies}")

実行結果

Aさんの趣味: {'料理', '読書', '映画', '音楽'}
Bさんの趣味: {'旅行', 'スポーツ', '映画', '音楽'}

共通の趣味: {'映画', '音楽'}
Aさんだけの趣味: {'料理', '読書'}
Bさんだけの趣味: {'旅行', 'スポーツ'}
全ての趣味: {'料理', '読書', '旅行', 'スポーツ', '映画', '音楽'}

例3: アクセス許可リストのチェック

セットの高速な検索を活用した例です。

コード:許可リストのチェック

# 許可されたユーザーのセット
allowed_users = {"user1", "user2", "user3", "admin"}

# ログインしようとしているユーザー
login_users = ["user1", "guest", "user2", "unknown", "admin"]

print("【アクセスチェック】")
for user in login_users:
    # in演算子でセット内を検索(非常に高速)
    if user in allowed_users:
        print(f"✓ {user}: アクセス許可")
    else:
        print(f"✗ {user}: アクセス拒否")

実行結果

【アクセスチェック】
✓ user1: アクセス許可
✗ guest: アクセス拒否
✓ user2: アクセス許可
✗ unknown: アクセス拒否
✓ admin: アクセス許可

例4: 2つのリストの比較

新旧のデータを比較して、追加・削除された項目を見つけます。

コード:データの差分を見つける

# 昨日の在庫
yesterday = {"りんご", "バナナ", "オレンジ", "ぶどう"}

# 今日の在庫
today = {"りんご", "バナナ", "メロン", "いちご"}

print(f"昨日の在庫: {yesterday}")
print(f"今日の在庫: {today}")

# 新しく入荷した商品(今日にあって昨日にない)
new_items = today - yesterday
print(f"\n新入荷: {new_items}")

# 売り切れた商品(昨日にあって今日にない)
sold_out = yesterday - today
print(f"売り切れ: {sold_out}")

# 変わらず在庫がある商品(共通)
still_in_stock = yesterday & today
print(f"引き続き在庫あり: {still_in_stock}")

実行結果

昨日の在庫: {'オレンジ', 'バナナ', 'ぶどう', 'りんご'}
今日の在庫: {'バナナ', 'いちご', 'メロン', 'りんご'}

新入荷: {'いちご', 'メロン'}
売り切れ: {'オレンジ', 'ぶどう'}
引き続き在庫あり: {'バナナ', 'りんご'}

✅ 5. ブール型(bool)とは何か?

ここからは、プログラミングで非常に重要な「ブール型」を学びます。

🔰 ブール型のイメージ

💡 ブール型とは

ブール型は、True(真)またはFalse(偽)の2つの値だけを持つ型です。

「はい」か「いいえ」、「オン」か「オフ」のように、2択で表せるデータです。

条件分岐(if文)や繰り返し(while文)の判定で使われます。

📝 ブール型の基本

コード:ブール型の基本

# ブール値を変数に代入
is_student = True
is_adult = False

print(is_student)
print(type(is_student))

print(is_adult)
print(type(is_adult))

実行結果

True
<class 'bool'>
False
<class 'bool'>

⚠️ 注意:大文字小文字に注意

TrueFalseは先頭が大文字です。

truefalse(小文字)はエラーになります。

📝 比較演算の結果はブール型

比較演算(==><など)の結果は、ブール型(True/False)になります。

コード:比較演算とブール型

# 比較演算の結果はTrueまたはFalse
print(10 > 5)    # 10は5より大きい? → True
print(10 < 5)    # 10は5より小さい? → False
print(10 == 10)  # 10は10と等しい? → True
print(10 != 5)   # 10は5と等しくない? → True

# 比較結果を変数に代入
age = 20
is_adult = age >= 18  # 18以上かどうか
print(f"年齢: {age}歳")
print(f"成人?: {is_adult}")

実行結果

True
False
True
True
年齢: 20歳
成人?: True

📘 比較演算子の一覧

演算子 意味 結果
== 等しい 5 == 5 True
!= 等しくない 5 != 3 True
> より大きい 5 > 3 True
< より小さい 5 < 3 False
>= 以上 5 >= 5 True
<= 以下 5 <= 3 False

📝 真偽値(Truthy/Falsy)

Pythonでは、True/False以外の値も「真」または「偽」として扱われます。

💡 Falseと判定される値(Falsy)

以下の値は、if文などでFalseとして扱われます:

False(ブール値)

None(何もない)

00.0(数値のゼロ)

""(空の文字列)

[](空のリスト)

()(空のタプル)

{}(空の辞書)

set()(空のセット)

それ以外は全てTrue!

コード:Falseと判定される値

# bool()でブール値に変換できる
print("【Falseになる値】")
print(f"bool(0): {bool(0)}")
print(f"bool(0.0): {bool(0.0)}")
print(f"bool(''): {bool('')}")
print(f"bool([]): {bool([])}")
print(f"bool(None): {bool(None)}")

実行結果

【Falseになる値】
bool(0): False
bool(0.0): False
bool(''): False
bool([]): False
bool(None): False

コード:Trueと判定される値

print("【Trueになる値】")
print(f"bool(1): {bool(1)}")
print(f"bool(-5): {bool(-5)}")
print(f"bool('Hello'): {bool('Hello')}")
print(f"bool([1, 2]): {bool([1, 2])}")
print(f"bool({{1, 2}}): {bool({1, 2})}")

実行結果

【Trueになる値】
bool(1): True
bool(-5): True
bool('Hello'): True
bool([1, 2]): True
bool({1, 2}): True

📝 if文での活用

この「真偽値」の特性は、if文で簡潔なコードを書くのに役立ちます。

コード:真偽値を活用したif文

# リストが空かどうかをチェック
items = []

# 長い書き方
if len(items) == 0:
    print("リストは空です(長い書き方)")

# 短い書き方(空のリストはFalseなので)
if not items:
    print("リストは空です(短い書き方)")

# 文字列が空かどうか
name = "太郎"

if name:  # 空でなければTrue
    print(f"こんにちは、{name}さん!")
else:
    print("名前が入力されていません")

実行結果

リストは空です(長い書き方)
リストは空です(短い書き方)
こんにちは、太郎さん!

🔀 6. 論理演算子

複数の条件を組み合わせるための「論理演算子」を学びましょう。

📘 論理演算子の一覧

演算子 意味 結果がTrueになる条件
and かつ(AND) 両方ともTrueの時だけTrue
or または(OR) どちらか一方がTrueならTrue
not 否定(NOT) TrueとFalseを反転

📝 and(かつ)- 両方ともTrueの時だけTrue

コード:and演算子

# andの基本
print("【andの真理値表】")
print(f"True and True: {True and True}")
print(f"True and False: {True and False}")
print(f"False and True: {False and True}")
print(f"False and False: {False and False}")

実行結果

【andの真理値表】
True and True: True
True and False: False
False and True: False
False and False: False

コード:andの実用例

# 運転できる条件:18歳以上 かつ 免許を持っている
age = 20
has_license = True

# 両方の条件を満たすか確認
can_drive = age >= 18 and has_license
print(f"年齢: {age}歳")
print(f"免許: {has_license}")
print(f"運転できる?: {can_drive}")

実行結果

年齢: 20歳
免許: True
運転できる?: True

💡 andのイメージ

「AかつB」- 両方の条件を満たす必要がある

例:「18歳以上」AND「免許を持っている」→ 両方OKなら運転できる

📝 or(または)- どちらか一方がTrueならTrue

コード:or演算子

# orの基本
print("【orの真理値表】")
print(f"True or True: {True or True}")
print(f"True or False: {True or False}")
print(f"False or True: {False or True}")
print(f"False or False: {False or False}")

実行結果

【orの真理値表】
True or True: True
True or False: True
False or True: True
False or False: False

コード:orの実用例

# 休める条件:週末 または 祝日
is_weekend = True
is_holiday = False

# どちらか一方でも満たせばOK
can_relax = is_weekend or is_holiday
print(f"週末: {is_weekend}")
print(f"祝日: {is_holiday}")
print(f"休める?: {can_relax}")

実行結果

週末: True
祝日: False
休める?: True

💡 orのイメージ

「AまたはB」- どちらか一方を満たせばOK

例:「週末」OR「祝日」→ どちらかなら休める

📝 not(否定)- True/Falseを反転

コード:not演算子

# notの基本
print("【notの真理値表】")
print(f"not True: {not True}")
print(f"not False: {not False}")

実行結果

【notの真理値表】
not True: False
not False: True

コード:notの実用例

# 外出できる条件:雨が降っていない
is_raining = False

# notで条件を反転
can_go_out = not is_raining
print(f"雨が降っている: {is_raining}")
print(f"外出できる?: {can_go_out}")

実行結果

雨が降っている: False
外出できる?: True

📝 複数の論理演算を組み合わせる

複数の条件を組み合わせて、より複雑な判定ができます。

コード:複雑な条件判定

# 入場条件:18歳以上 かつ (チケットを持っている または お金を持っている)
age = 25
has_ticket = True
has_money = False

# カッコを使って優先順位を明確に
can_enter = age >= 18 and (has_ticket or has_money)

print(f"年齢: {age}歳")
print(f"チケット: {has_ticket}")
print(f"お金: {has_money}")
print(f"入場できる?: {can_enter}")

実行結果

年齢: 25歳
チケット: True
お金: False
入場できる?: True

💡 論理演算子の優先順位

優先順位は not > and > or の順です。

ただし、カッコ () を使うと優先順位を明確にできます。

複雑な条件は、カッコを使って書くことをお勧めします。

コード:優先順位の確認

# カッコなし - andが先に評価される
result1 = True or False and False
print(f"True or False and False = {result1}")  # True

# カッコあり - カッコ内が先に評価される
result2 = (True or False) and False
print(f"(True or False) and False = {result2}")  # False

実行結果

True or False and False = True
(True or False) and False = False

💡 解説

True or False and Falseは、andが先なので

= True or (False and False)

= True or False

= True

(True or False) and Falseは、カッコが先なので

= True and False

= False

❓ 7. None型

Pythonには「値がない」ことを表す特別な値があります。それがNoneです。

🔰 Noneとは?

💡 Noneのイメージ

Noneは「何もない」「値がない」ことを表す特別な値です。

他のプログラミング言語では nullnil と呼ばれることもあります。

「まだ値が決まっていない」「結果がない」といった状況で使います。

📝 Noneの基本

コード:Noneの基本

# Noneを変数に代入
result = None

print(result)
print(type(result))

実行結果

None
<class 'NoneType'>

📝 関数が何も返さない場合はNone

return文がない関数や、returnだけで値を返さない関数は、Noneを返します。

コード:関数とNone

# 何も返さない関数
def say_hello():
    print("こんにちは!")
    # return文がない

# 関数を呼び出して、戻り値を受け取る
result = say_hello()
print(f"戻り値: {result}")

実行結果

こんにちは!
戻り値: None

📝 Noneのチェック方法

Noneかどうかをチェックするには、is演算子を使います。

コード:Noneのチェック

value = None

# is演算子でNoneをチェック(推奨)
if value is None:
    print("valueはNoneです")

# is notでNoneでないことをチェック
if value is not None:
    print("valueは値があります")
else:
    print("valueは値がありません")

実行結果

valueはNoneです
valueは値がありません

⚠️ なぜ == ではなく is を使う?

==でも動きますが、isを使うのがPythonの推奨スタイルです。

isは「同一オブジェクトかどうか」をチェックします。

Noneはプログラム全体で1つしかないため、isで比較するのが適切です。

📝 Noneの実用例

Noneは様々な場面で使われます。

コード:初期値としてのNone

# まだ値が決まっていない変数
user_name = None

# 値が設定されているかチェック
if user_name is None:
    user_name = "ゲスト"

print(f"ようこそ、{user_name}さん!")

実行結果

ようこそ、ゲストさん!

コード:関数のオプション引数

# デフォルト値としてNoneを使う
def greet(name, title=None):
    if title is None:
        # titleが指定されていない場合
        print(f"こんにちは、{name}さん")
    else:
        # titleが指定されている場合
        print(f"こんにちは、{title}{name}さん")

# 引数を1つだけ渡す
greet("太郎")

# 引数を2つ渡す
greet("花子", "博士")

実行結果

こんにちは、太郎さん
こんにちは、博士花子さん

コード:検索結果がない場合

# ユーザーを検索する関数
def find_user(user_id, users):
    for user in users:
        if user["id"] == user_id:
            return user  # 見つかったら返す
    return None  # 見つからなければNone

# ユーザーリスト
users = [
    {"id": 1, "name": "太郎"},
    {"id": 2, "name": "花子"},
]

# ユーザーを検索
result1 = find_user(1, users)
result2 = find_user(99, users)

# 結果をチェック
if result1 is not None:
    print(f"見つかりました: {result1['name']}")
else:
    print("ユーザーが見つかりません")

if result2 is not None:
    print(f"見つかりました: {result2['name']}")
else:
    print("ユーザーが見つかりません")

実行結果

見つかりました: 太郎
ユーザーが見つかりません

📘 None、False、0、空文字の違い

📌 これらは全て「偽」として扱われますが、意味が異なります

意味
None NoneType 値がない、未定義
False bool 偽(明示的な真偽値)
0 int 数値のゼロ
"" str 空の文字列
[] list 空のリスト

🔄 8. データ型の変換

異なるデータ型の間で変換する方法を学びましょう。

📘 型変換の関数一覧

関数 変換先
int() 整数 int("10") → 10
float() 小数 float("3.14") → 3.14
str() 文字列 str(100) → "100"
bool() ブール bool(1) → True
list() リスト list({1,2}) → [1,2]
tuple() タプル tuple([1,2]) → (1,2)
set() セット set([1,2,1]) → {1,2}

📝 ブール型への変換

コード:bool()での変換

# 数値をブールに変換
print(f"bool(0): {bool(0)}")      # False
print(f"bool(1): {bool(1)}")      # True
print(f"bool(-5): {bool(-5)}")    # True

# 文字列をブールに変換
print(f"bool(''): {bool('')}")            # False
print(f"bool('Hello'): {bool('Hello')}")  # True
print(f"bool('False'): {bool('False')}")  # True(文字列"False"は空でないのでTrue!)

実行結果

bool(0): False
bool(1): True
bool(-5): True
bool(''): False
bool('Hello'): True
bool('False'): True

⚠️ 注意

bool("False")Trueになります!

文字列"False"は空ではないので、Trueと判定されます。

📝 リストとセットの相互変換

コード:リストとセットの変換

# リストからセットへ(重複が削除される)
my_list = [1, 2, 3, 2, 1, 4]
my_set = set(my_list)
print(f"リスト: {my_list}")
print(f"セット: {my_set}")

# セットからリストへ
back_to_list = list(my_set)
print(f"リストに戻す: {back_to_list}")

# ソートしてリストに
sorted_list = sorted(my_set)
print(f"ソートしてリスト: {sorted_list}")

実行結果

リスト: [1, 2, 3, 2, 1, 4]
セット: {1, 2, 3, 4}
リストに戻す: [1, 2, 3, 4]
ソートしてリスト: [1, 2, 3, 4]

📝 文字列からセットへの変換

コード:文字列からセット

# 文字列をセットに変換(1文字ずつバラバラになる)
text = "hello"
char_set = set(text)
print(f"文字列: {text}")
print(f"セット: {char_set}")

# 重複する文字は1つになる
text2 = "Mississippi"
char_set2 = set(text2)
print(f"\n文字列: {text2}")
print(f"セット: {char_set2}")
print(f"ユニークな文字数: {len(char_set2)}")

実行結果

文字列: hello
セット: {'h', 'l', 'o', 'e'}

文字列: Mississippi
セット: {'M', 'i', 's', 'p'}
ユニークな文字数: 4

📝 type()とisinstance()で型を確認

コード:型の確認

# type()で型を確認
print(f"type(True): {type(True)}")
print(f"type(None): {type(None)}")
print(f"type({{1, 2}}): {type({1, 2})}")

# isinstance()で型をチェック
value = {1, 2, 3}

# 特定の型かどうかを確認
print(f"\nvalueはセット?: {isinstance(value, set)}")
print(f"valueはリスト?: {isinstance(value, list)}")

# 複数の型のどれかかを確認
number = 10
print(f"numberはintかfloat?: {isinstance(number, (int, float))}")

実行結果

type(True): <class 'bool'>
type(None): <class 'NoneType'>
type({1, 2}): <class 'set'>

valueはセット?: True
valueはリスト?: False
numberはintかfloat?: True

💡 type()とisinstance()の違い

type(value) → 値の型を返す

isinstance(value, 型) → 指定した型かどうかをTrue/Falseで返す

条件分岐で使う場合は isinstance() の方が便利です。

📝 練習問題(10問)

ここまで学んだことを実際に手を動かして確認しましょう。

問題1:セットの作成(初級)

📋 問題

3つ以上の数値を含むセットを作成し、表示してください。

解答を見る

コード

# セットは波カッコ {} で作る
numbers = {1, 2, 3, 4, 5}
print(numbers)
print(type(numbers))

実行結果

{1, 2, 3, 4, 5}
<class 'set'>

問題2:重複の削除(初級)

📋 問題

リスト [1, 2, 3, 2, 4, 1, 5, 3] から重複を削除して、ユニークな値だけのソート済みリストを作成してください。

解答を見る

コード

numbers = [1, 2, 3, 2, 4, 1, 5, 3]
print(f"元のリスト: {numbers}")

# set()で重複削除し、sorted()でソート
unique_sorted = sorted(set(numbers))
print(f"重複削除&ソート: {unique_sorted}")

実行結果

元のリスト: [1, 2, 3, 2, 4, 1, 5, 3]
重複削除&ソート: [1, 2, 3, 4, 5]

問題3:セットへの追加(初級)

📋 問題

空のセットを作成し、add()メソッドで3つの果物を追加してください。

解答を見る

コード

# 空のセットはset()で作る({}は辞書になるので注意)
fruits = set()
print(f"最初: {fruits}")

# add()で1つずつ追加
fruits.add("りんご")
fruits.add("バナナ")
fruits.add("オレンジ")

print(f"追加後: {fruits}")

実行結果

最初: set()
追加後: {'バナナ', 'オレンジ', 'りんご'}

問題4:ブール値の確認(初級)

📋 問題

以下の値をブール型に変換して表示してください:0、1、""、"Hello"、[]、[1, 2]

解答を見る

コード

# bool()でブール値に変換
print(f"bool(0): {bool(0)}")           # False(ゼロ)
print(f"bool(1): {bool(1)}")           # True(ゼロ以外)
print(f"bool(''): {bool('')}")         # False(空文字列)
print(f"bool('Hello'): {bool('Hello')}")  # True(空でない文字列)
print(f"bool([]): {bool([])}")         # False(空リスト)
print(f"bool([1, 2]): {bool([1, 2])}")    # True(空でないリスト)

実行結果

bool(0): False
bool(1): True
bool(''): False
bool('Hello'): True
bool([]): False
bool([1, 2]): True

問題5:論理演算(初級)

📋 問題

以下の論理演算の結果を表示してください:True and True、True and False、True or False、not True

解答を見る

コード

# and: 両方Trueの時だけTrue
print(f"True and True: {True and True}")
print(f"True and False: {True and False}")

# or: どちらか一方がTrueならTrue
print(f"True or False: {True or False}")

# not: TrueとFalseを反転
print(f"not True: {not True}")

実行結果

True and True: True
True and False: False
True or False: True
not True: False

問題6:和集合(中級)

📋 問題

2つのセット set1 = {1, 2, 3}set2 = {3, 4, 5} の和集合を求めてください。

解答を見る

コード

set1 = {1, 2, 3}
set2 = {3, 4, 5}

# | 演算子で和集合(両方の全要素を合わせる)
union = set1 | set2
print(f"set1: {set1}")
print(f"set2: {set2}")
print(f"和集合: {union}")

実行結果

set1: {1, 2, 3}
set2: {3, 4, 5}
和集合: {1, 2, 3, 4, 5}

問題7:積集合(中級)

📋 問題

2つのセット set1 = {1, 2, 3, 4}set2 = {3, 4, 5, 6} の積集合(共通要素)を求めてください。

解答を見る

コード

set1 = {1, 2, 3, 4}
set2 = {3, 4, 5, 6}

# & 演算子で積集合(両方に共通する要素)
intersection = set1 & set2
print(f"set1: {set1}")
print(f"set2: {set2}")
print(f"積集合: {intersection}")

実行結果

set1: {1, 2, 3, 4}
set2: {3, 4, 5, 6}
積集合: {3, 4}

問題8:Noneのチェック(中級)

📋 問題

変数 valueNone を代入し、その変数が None かどうかをチェックして、適切なメッセージを表示してください。

解答を見る

コード

value = None

# is演算子でNoneをチェック
if value is None:
    print("valueはNoneです(値がありません)")
else:
    print(f"valueの値は{value}です")

実行結果

valueはNoneです(値がありません)

問題9:複雑な条件判定(中級)

📋 問題

年齢 age = 20、学生 is_student = True として、「20歳以上で学生」という条件を判定してください。

解答を見る

コード

age = 20
is_student = True

# andで両方の条件を確認
if age >= 20 and is_student:
    print("20歳以上の学生です")
else:
    print("条件を満たしていません")

# 確認用
print(f"年齢: {age}歳")
print(f"学生: {is_student}")
print(f"20歳以上かつ学生: {age >= 20 and is_student}")

実行結果

20歳以上の学生です
年齢: 20歳
学生: True
20歳以上かつ学生: True

問題10:セットの活用(上級)

📋 問題

2つのリストがあります:

list1 = ["りんご", "バナナ", "オレンジ", "ぶどう"]

list2 = ["バナナ", "ぶどう", "メロン", "いちご"]

以下を求めてください:

・両方に含まれる果物

・list1だけに含まれる果物

・どちらかに含まれる果物(重複なし)

解答を見る

コード

list1 = ["りんご", "バナナ", "オレンジ", "ぶどう"]
list2 = ["バナナ", "ぶどう", "メロン", "いちご"]

# リストをセットに変換
set1 = set(list1)
set2 = set(list2)

print(f"list1: {list1}")
print(f"list2: {list2}")

# 両方に含まれる(積集合)
common = set1 & set2
print(f"\n両方に含まれる: {common}")

# list1だけに含まれる(差集合)
only_list1 = set1 - set2
print(f"list1だけに含まれる: {only_list1}")

# どちらかに含まれる(和集合)
all_fruits = set1 | set2
print(f"どちらかに含まれる: {all_fruits}")

実行結果

list1: ['りんご', 'バナナ', 'オレンジ', 'ぶどう']
list2: ['バナナ', 'ぶどう', 'メロン', 'いちご']

両方に含まれる: {'バナナ', 'ぶどう'}
list1だけに含まれる: {'オレンジ', 'りんご'}
どちらかに含まれる: {'オレンジ', 'バナナ', 'いちご', 'メロン', 'ぶどう', 'りんご'}

❓ よくある質問

Q1: セットとリストはどう使い分ける?

順序が重要で、重複を許す場合はリストを使います。

重複を許さず、高速な検索が必要な場合はセットを使います。

また、集合演算(和集合、積集合など)が必要な場合もセットが便利です。

Q2: セットの順序は保証される?

Python 3.7以降では挿入順序が保持されますが、セットは本来「順序がない」データ構造です。

順序に依存するコードは書かないようにしましょう。

順序が重要な場合はリストを使ってください。

Q3: NoneとFalseの違いは?

Noneは「値がない」ことを表し、Falseは「偽」を表します。

どちらもif文でFalseと判定されますが、意味が異なります。

Noneは未初期化や値なしを、Falseは明示的な偽を表すのに使います。

Q4: なぜ空の{}はセットではなく辞書?

歴史的な理由で、{}は辞書として解釈されます。

空のセットを作る場合は必ずset()を使ってください。

要素があるセット{1, 2, 3}は波カッコで作成できます。

Q5: セットにリストを入れられる?

いいえ、セットの要素は変更不可(イミュータブル)である必要があります。

リストは変更可能なので入れられません。タプルなら入れられます。

例:{(1,2), (3,4)}はOK、{[1,2], [3,4]}はエラーです。

🎉 ステップ9のまとめ

✅ このステップで学んだこと

✓ セットは重複を許さないデータの集まり(波カッコ {} で作成)

✓ 空のセットは set() で作る({} は辞書になる)

✓ add()で追加、remove()やdiscard()で削除

✓ 集合演算:和集合(|)、積集合(&)、差集合(-)、対称差(^)

✓ セットは高速な検索と重複削除に便利

✓ ブール型はTrue/Falseの2つの値

✓ 論理演算子:and(かつ)、or(または)、not(否定)

✓ 0、空文字、空リストなどはFalseと判定される

✓ Noneは「値がない」ことを表す特別な値

✓ Noneのチェックには is を使う

💪 次のステップへ

セットとブール型をマスターしました!

セットは重複削除や集合演算に、ブール型は条件判定に欠かせません。

これらをうまく使いこなせると、コードがよりシンプルで効率的になります。

次のステップでは、条件分岐について学びます。

if文を使って、プログラムの流れを制御する方法を習得しましょう!

📝

学習メモ

Pythonプログラミング基礎 - Step 9

📋 過去のメモ一覧
#artnasekai #学習メモ
LINE