STEP 3

Python 基本構文リファレンス

変数・データ型・演算子・条件分岐・ループ・コレクション・内包表記・例外処理まで、Pythonの核となる文法を豊富なコード例とともに解説します。

📖 リファレンス形式🎯 初心者〜中級者

1. 変数とデータ型

Pythonは動的型付け言語です。変数の型を宣言する必要はなく、代入した値によって型が自動的に決まります。

# 変数の代入
name = "Alice"          # str(文字列)
age = 25                # int(整数)
height = 165.5          # float(浮動小数点数)
is_student = True       # bool(真偽値)
nothing = None          # NoneType(空値)

# 型の確認
print(type(name))       # <class 'str'>
print(type(age))        # <class 'int'>
print(type(height))     # <class 'float'>
print(type(is_student)) # <class 'bool'>

# 型変換(キャスト)
num_str = "42"
num_int = int(num_str)      # "42" → 42
num_float = float(num_str)  # "42" → 42.0
back_to_str = str(num_int)  # 42 → "42"

# 複数の変数を同時に代入
x, y, z = 1, 2, 3
a = b = c = 0   # 全て同じ値

型アノテーション(Python 3.5+)

変数や関数の型をコメントとして記述できます(強制ではありませんが、コードの可読性が上がります)。

name: str = "Alice"
age: int = 25
scores: list[int] = [90, 85, 92]
info: dict[str, str] = {"city": "Tokyo", "country": "Japan"}

2. 演算子

算術演算子

a, b = 10, 3

print(a + b)    # 13  加算
print(a - b)    # 7   減算
print(a * b)    # 30  乗算
print(a / b)    # 3.333... 除算(常にfloat)
print(a // b)   # 3   整数除算(切り捨て)
print(a % b)    # 1   剰余(余り)
print(a ** b)   # 1000 べき乗

比較演算子

x = 5
print(x == 5)   # True   等しい
print(x != 3)   # True   等しくない
print(x > 3)    # True   より大きい
print(x < 10)   # True   より小さい
print(x >= 5)   # True   以上
print(x <= 5)   # True   以下

論理演算子・代入演算子

# 論理演算子
print(True and False)  # False
print(True or False)   # True
print(not True)        # False

# 代入演算子(複合代入)
n = 10
n += 5   # n = n + 5  → 15
n -= 3   # n = n - 3  → 12
n *= 2   # n = n * 2  → 24
n //= 5  # n = n // 5 → 4
n **= 3  # n = n ** 3 → 64

# ウォルラス演算子(:= Python 3.8+)
# 代入と同時に使用する
import re
if m := re.search(r"\d+", "abc123"):
    print(m.group())  # "123"

3. 文字列操作

s = "Hello, Python!"

# 基本操作
print(len(s))           # 14  文字数
print(s.upper())        # HELLO, PYTHON!
print(s.lower())        # hello, python!
print(s.replace("Python", "World"))  # Hello, World!
print(s.split(", "))    # ['Hello', 'Python!']
print(s.strip())        # 前後の空白を削除
print(s.startswith("Hello"))  # True
print(s.endswith("!"))        # True
print("Python" in s)          # True

# スライス
print(s[0])     # H
print(s[-1])    # !
print(s[0:5])   # Hello
print(s[7:])    # Python!
print(s[::-1])  # !nohtyP ,olleH(逆順)

# 文字列フォーマット(f-string が最も推奨)
name = "Alice"
age = 25
print(f"名前: {name}, 年齢: {age}歳")
print(f"{3.14159:.2f}")        # 小数点2桁 → 3.14
print(f"{1000000:,}")          # カンマ区切り → 1,000,000
print(f"{'left':<10}|")        # 左寄せ10文字
print(f"{'right':>10}|")       # 右寄せ10文字
print(f"{'center':^10}|")      # 中央揃え10文字

# 複数行文字列
multiline = """
これは
複数行の
文字列です。
"""

# 文字列の結合
words = ["Python", "は", "楽しい"]
print("".join(words))        # Python は楽しい
print(" ".join(words))       # Python は 楽しい

4. 条件分岐(if / elif / else)

# 基本のif文
score = 85

if score >= 90:
    print("優秀")
elif score >= 70:
    print("合格")
elif score >= 60:
    print("ぎりぎり合格")
else:
    print("不合格")
# 出力: 合格

# 三項演算子(条件式)
result = "合格" if score >= 60 else "不合格"
print(result)  # 合格

# 複合条件
age = 20
has_id = True
if age >= 18 and has_id:
    print("入場できます")

# in演算子
fruits = ["apple", "banana", "cherry"]
if "apple" in fruits:
    print("りんごがあります")

# match文(Python 3.10+)
command = "quit"
match command:
    case "quit":
        print("終了します")
    case "help":
        print("ヘルプを表示します")
    case _:
        print(f"不明なコマンド: {command}")

# 真偽値の評価(falsy な値)
# False, 0, 0.0, "", [], {}, (), None → すべて False として扱われる
empty_list = []
if not empty_list:
    print("リストが空です")

5. ループ(for / while)

# forループ - rangeを使った繰り返し
for i in range(5):
    print(i)       # 0, 1, 2, 3, 4

for i in range(1, 6):
    print(i)       # 1, 2, 3, 4, 5

for i in range(0, 10, 2):
    print(i)       # 0, 2, 4, 6, 8

# リストのループ
fruits = ["apple", "banana", "cherry"]
for fruit in fruits:
    print(fruit)

# enumerate - インデックス付きループ
for i, fruit in enumerate(fruits):
    print(f"{i}: {fruit}")
# 0: apple / 1: banana / 2: cherry

# zip - 複数のリストを同時にループ
names = ["Alice", "Bob", "Carol"]
scores = [85, 90, 78]
for name, score in zip(names, scores):
    print(f"{name}: {score}点")

# whileループ
count = 0
while count < 5:
    print(count)
    count += 1

# break と continue
for i in range(10):
    if i == 3:
        continue    # 3をスキップ
    if i == 7:
        break       # 7で終了
    print(i)        # 0, 1, 2, 4, 5, 6

# for-else(breakされなかった場合に実行)
for i in range(5):
    if i == 10:
        break
else:
    print("10は見つかりませんでした")

6. リスト(list)

リストは順序があり、変更可能な要素のコレクションです。

# リストの作成
nums = [3, 1, 4, 1, 5, 9, 2, 6]
mixed = [1, "hello", True, 3.14, None]

# 基本操作
nums.append(7)          # 末尾に追加
nums.insert(0, 0)       # 位置0に挿入
nums.remove(1)          # 最初の1を削除
popped = nums.pop()     # 末尾を取り出して削除
popped_i = nums.pop(2)  # インデックス2を取り出して削除
nums.extend([10, 11])   # 別のリストを結合

# 検索
print(5 in nums)         # True
print(nums.index(9))     # 9の位置
print(nums.count(1))     # 1の個数

# ソート
nums.sort()              # 昇順(元のリストを変更)
nums.sort(reverse=True)  # 降順
sorted_nums = sorted(nums)  # 新しいリストを返す

# スライス
a = [0, 1, 2, 3, 4, 5]
print(a[1:4])    # [1, 2, 3]
print(a[::2])    # [0, 2, 4]  偶数インデックス
print(a[::-1])   # [5, 4, 3, 2, 1, 0]  逆順

# コピー(注意:= はコピーでなく参照)
b = a.copy()     # 正しいコピー方法
c = a[:]         # スライスでのコピー
import copy
d = copy.deepcopy(a)  # ネストしたリストのコピー

# 2Dリスト(行列)
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
print(matrix[1][2])   # 6(2行3列)

7. タプル(tuple)

タプルは順序があり、変更不可(イミュータブル)なコレクションです。座標やRGBカラーなど「変わらない組み合わせ」に使います。

# タプルの作成
point = (3, 4)
rgb = (255, 128, 0)
single = (42,)    # 要素1つのタプルはカンマが必要

# アンパック(分解代入)
x, y = point
print(x, y)    # 3 4

r, g, b = rgb
print(r, g, b) # 255 128 0

# アスタリスクでの分解
first, *rest = [1, 2, 3, 4, 5]
print(first)  # 1
print(rest)   # [2, 3, 4, 5]

# namedtuple - 名前付きタプル
from collections import namedtuple
Point = namedtuple('Point', ['x', 'y'])
p = Point(x=3, y=4)
print(p.x, p.y)   # 3 4
print(p[0], p[1]) # 3 4  インデックスでも可

8. 辞書(dict)

辞書はキーと値のペアを管理するコレクションです。高速なキー検索が特徴です。

# 辞書の作成
person = {"name": "Alice", "age": 25, "city": "Tokyo"}
empty = {}
from_keys = dict.fromkeys(["a", "b", "c"], 0)  # {"a": 0, "b": 0, "c": 0}

# アクセスと更新
print(person["name"])            # Alice
print(person.get("email", "N/A")) # 存在しないキーはデフォルト値

person["email"] = "alice@example.com"  # 追加
person["age"] = 26                      # 更新
del person["city"]                      # 削除

# キー・値・ペアの取得
print(person.keys())    # dict_keys(['name', 'age', 'email'])
print(person.values())  # dict_values(['Alice', 26, 'alice@example.com'])
print(person.items())   # dict_items([...])

# ループ
for key, value in person.items():
    print(f"{key}: {value}")

# 辞書の結合(Python 3.9+)
d1 = {"a": 1, "b": 2}
d2 = {"b": 3, "c": 4}
merged = d1 | d2   # {"a": 1, "b": 3, "c": 4}(d2が優先)

# defaultdict
from collections import defaultdict
word_count = defaultdict(int)
for word in "hello world hello python".split():
    word_count[word] += 1
print(dict(word_count))  # {'hello': 2, 'world': 1, 'python': 1}

9. 集合(set)

集合は重複なし・順序なしのコレクションです。和集合・積集合・差集合などの集合演算が使えます。

a = {1, 2, 3, 4, 5}
b = {3, 4, 5, 6, 7}

# 集合演算
print(a | b)   # {1,2,3,4,5,6,7}  和集合
print(a & b)   # {3,4,5}           積集合(共通要素)
print(a - b)   # {1,2}             差集合(aにありbにない)
print(a ^ b)   # {1,2,6,7}         対称差(どちらか一方だけ)

# 重複の削除によく使う
nums = [1, 2, 2, 3, 3, 3, 4]
unique = list(set(nums))  # [1, 2, 3, 4](順序は保証されない)

# 追加・削除
a.add(6)
a.remove(1)      # 存在しない場合はエラー
a.discard(100)   # 存在しなくてもエラーにならない

10. 内包表記

内包表記はリスト・辞書・集合を簡潔に作成するPythonらしい記法です。forループを1行で書けます。

# リスト内包表記
squares = [x**2 for x in range(10)]
# [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

# 条件付きリスト内包表記
evens = [x for x in range(20) if x % 2 == 0]
# [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

# 文字列のリスト内包表記
words = ["hello", "world", "python"]
upper = [w.upper() for w in words]
# ['HELLO', 'WORLD', 'PYTHON']

# 辞書内包表記
square_dict = {x: x**2 for x in range(5)}
# {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}

# 集合内包表記
unique_lengths = {len(w) for w in words}
# {5, 6}

# ジェネレーター式(メモリ効率が良い)
gen = (x**2 for x in range(1000000))
print(next(gen))  # 0
print(sum(gen))   # 残りの合計(メモリを使わずに計算)

# ネストした内包表記
matrix = [[1,2,3],[4,5,6],[7,8,9]]
flat = [num for row in matrix for num in row]
# [1, 2, 3, 4, 5, 6, 7, 8, 9]

11. 例外処理(try / except)

例外処理を使うと、エラーが発生してもプログラムをクラッシュさせずに対処できます。

# 基本の try-except
try:
    num = int(input("数字を入力: "))
    result = 10 / num
    print(f"結果: {result}")
except ValueError:
    print("数字を入力してください")
except ZeroDivisionError:
    print("0で割ることはできません")
except Exception as e:
    print(f"予期しないエラー: {e}")
else:
    # 例外が発生しなかった場合に実行
    print("計算成功!")
finally:
    # 例外の有無に関わらず必ず実行
    print("処理終了")

# 例外を発生させる
def validate_age(age):
    if not isinstance(age, int):
        raise TypeError("年齢は整数で入力してください")
    if age < 0 or age > 150:
        raise ValueError(f"年齢の範囲が不正です: {age}")
    return age

# カスタム例外クラス
class AppError(Exception):
    def __init__(self, message, code=None):
        super().__init__(message)
        self.code = code

try:
    raise AppError("アプリエラーが発生しました", code=404)
except AppError as e:
    print(f"エラー {e.code}: {e}")

# よく発生する例外の種類
# ValueError      - 不正な値(int("abc")など)
# TypeError       - 型の不一致("a" + 1 など)
# KeyError        - 辞書に存在しないキー
# IndexError      - リストの範囲外アクセス
# FileNotFoundError - ファイルが見つからない
# ZeroDivisionError - 0除算
# AttributeError  - 存在しない属性へのアクセス

12. ファイル操作

# ファイルの書き込み(with文を使うのが推奨)
with open("data.txt", "w", encoding="utf-8") as f:
    f.write("Hello, Python!\n")
    f.write("ファイル操作の例\n")

# ファイルの読み込み
with open("data.txt", "r", encoding="utf-8") as f:
    content = f.read()      # 全内容を文字列で
    print(content)

# 行ごとに読み込む
with open("data.txt", "r", encoding="utf-8") as f:
    for line in f:
        print(line.strip())

# 追記モード
with open("data.txt", "a", encoding="utf-8") as f:
    f.write("追加行\n")

# JSONファイルの読み書き
import json

data = {"name": "Alice", "scores": [90, 85, 92]}
with open("data.json", "w", encoding="utf-8") as f:
    json.dump(data, f, ensure_ascii=False, indent=2)

with open("data.json", "r", encoding="utf-8") as f:
    loaded = json.load(f)
print(loaded["name"])  # Alice

# pathlib を使ったパス操作(Python 3.4+)
from pathlib import Path

p = Path("data.txt")
print(p.exists())       # ファイルが存在するか
print(p.stem)           # "data"(拡張子なし)
print(p.suffix)         # ".txt"(拡張子)
print(p.parent)         # 親ディレクトリ

# ディレクトリのファイル一覧
folder = Path(".")
for f in folder.glob("*.py"):
    print(f)

13. 実践ヒント・よくある落とし穴

基本構文を覚えても、実際にコードを書き始めると「動くけど何かおかしい」と感じる場面が必ず出てきます。ここでは初学者がつまずきがちなポイントと、Python らしい書き方の指針をまとめます。

13.1 「等しい」の落とし穴 — ==is の使い分け

初学者が最も間違えやすいのが ==is の混同です。== は値の等価性、is は同一オブジェクトかどうかを判定します。原則として、値を比較したいときは == を使い、isNoneTrueFalse との比較にだけ使うのが安全です。

a = [1, 2, 3]
b = [1, 2, 3]
print(a == b)   # True  値が同じ
print(a is b)   # False 別のオブジェクト

# None の判定は is で行うのが慣例
x = None
if x is None:          # ✅ 正しい
    print("xは未設定")
if x == None:          # ❌ 動くが非推奨(PEP 8)
    pass

13.2 デフォルト引数の罠 — 可変オブジェクトを書いてはいけない

関数のデフォルト引数に []{} を書くと、同じオブジェクトが関数呼び出し間で共有されるという直感に反する挙動になります。これは Python の言語仕様上の重要な落とし穴です。

# ❌ 罠:デフォルト引数にリストを直接書く
def add_item(item, items=[]):
    items.append(item)
    return items

print(add_item("a"))   # ['a']
print(add_item("b"))   # ['a', 'b']  ← 前の呼び出しの結果が残る!
print(add_item("c"))   # ['a', 'b', 'c']

# ✅ 正しい書き方:None を使って関数内で初期化
def add_item(item, items=None):
    if items is None:
        items = []
    items.append(item)
    return items

print(add_item("a"))   # ['a']
print(add_item("b"))   # ['b']  ← 期待通り

13.3 ループ中にリストを変更してはいけない

反復処理中のリストに対して appendremove を行うと、インデックスがずれて要素が飛ばされたり、無限ループになることがあります。安全に書くには、新しいリストを作って受け取るか、コピーを反復対象にするのが鉄則です。

nums = [1, 2, 3, 4, 5, 6]

# ❌ 反復中の remove は要素を飛ばす
for n in nums:
    if n % 2 == 0:
        nums.remove(n)
# 結果: [1, 3, 5, 6]  ← 6が残る!

# ✅ 内包表記で新しいリストを作る(推奨)
nums = [1, 2, 3, 4, 5, 6]
odd = [n for n in nums if n % 2 != 0]

# ✅ コピーを反復対象にする
for n in nums[:]:   # スライスでコピー
    if n % 2 == 0:
        nums.remove(n)

13.4 文字列結合は + ではなく join を使う

文字列を多数結合するときに += を使うと、Python は内部で毎回新しい文字列を生成するため、要素数が増えると急激に遅くなります(O(n²) になる)。str.join を使えば一度のメモリ割り当てで完了し、可読性も上がります。

words = ["Python", "is", "fun"]

# ❌ 遅い書き方
result = ""
for w in words:
    result += w + " "

# ✅ join を使う(高速・短い)
result = " ".join(words)

# 数値を結合する場合は str に変換
nums = [1, 2, 3]
result = ",".join(str(n) for n in nums)   # "1,2,3"

13.5 例外は「具体的な型」で受け止める

裸の except:except Exception: は、システム終了やキーボード割り込みまで捕まえてしまうため、原則として書いてはいけません。想定する例外の型を明示することが、堅牢なコードへの第一歩です。

# ❌ ベア except は禁止(バグを覆い隠す)
try:
    do_something()
except:
    pass  # 何が起きたのかわからない

# ❌ 広すぎる
try:
    do_something()
except Exception as e:
    print(f"エラー: {e}")  # KeyboardInterrupt 等まで握りつぶす

# ✅ 想定する例外を具体的に
try:
    num = int(user_input)
    result = 10 / num
except ValueError:
    print("整数を入力してください")
except ZeroDivisionError:
    print("0 では割れません")

13.6 文字列フォーマットは f-string が最短

Python 3.6 以降、文字列フォーマットは f"..." が標準です。% 演算子や str.format() より短く、読みやすく、実行速度も最速です。新規コードでは f-string 一択と考えて問題ありません。

name = "Alice"
age = 30
price = 1234.5678

# 旧スタイル(非推奨)
print("名前: %s, 年齢: %d" % (name, age))
print("名前: {}, 年齢: {}".format(name, age))

# ✅ f-string(推奨)
print(f"名前: {name}, 年齢: {age}")

# 桁数指定・桁区切り・小数点以下
print(f"価格: {price:,.2f} 円")   # 1,234.57 円
print(f"パディング: {age:>5}")    # 右寄せ5桁

# 式の埋め込みも可能
nums = [1, 2, 3]
print(f"合計: {sum(nums)}, 平均: {sum(nums)/len(nums):.1f}")

13.7 内包表記は「読める範囲」で使う

リスト内包表記は強力ですが、ネストが深くなったり条件が複雑になると一行で読めなくなります。3 行以上に分解できるなら、通常の for ループに戻す方が読みやすいのが現場の感覚です。

# ✅ シンプルな内包表記(OK)
squares = [x**2 for x in range(10)]
evens = [x for x in nums if x % 2 == 0]

# ⚠️ 複雑になったら通常 for に戻す
# 読めない例
result = [[x*y for y in range(3) if y > 0] for x in range(5) if x % 2 == 1]

# 読める書き方
result = []
for x in range(5):
    if x % 2 != 1:
        continue
    row = []
    for y in range(3):
        if y > 0:
            row.append(x * y)
    result.append(row)
💡
Python らしい書き方を身につけるコツ

「動けば良い」コードと「Python らしい」コードの差は、ループ・条件分岐の組み立て方・命名・例外の扱い方に現れます。本サイトの初心者用アプリ 100 本中級者用アプリ 100 本では、ここで紹介したパターンが繰り返し登場します。実例に触れることで、自然と Python らしい書き方が身についていきます。

🎉
基本構文をマスター!次は関数を学ぼう

Pythonの基本構文を学びました。次は関数を使ってコードをより整理された構造にしましょう。

関数を学ぶ →

📚
書籍でじっくり固めたい方へ

Webと書籍の併用は理解の定着に効果的です。図解豊富な入門書から実践書まで、Pythonおすすめ書籍【2026年版】で学習段階別にまとめています。