Python / LESSON 06 / PY06

Python:リストとタプル

1学習の目的

2基礎解説

やりたいこと書き方結果・意味
リストを作るitems = ["a", "b", "c"]順序あり・後から変更できる
取り出すitems[0] / items[-1]先頭は0番、末尾は-1
一部を切り出すitems[1:3]1番以上3番未満(終了は含まない)
変更できない並びpoint = (35.6, 139.7)タプル。作った後は書き換え不可
✅ 覚えるべき重要ポイント
  1. 番号は0始まり。3個のリストの番号は 0,1,2。末尾は items[-1]、個数は len(items)
  2. 追加は append(値)、削除は remove(値) または pop(番号)
  3. スライス items[1:4] は「1以上4未満」。rangeと同じで終わりは含まないitems[:3] で先頭3件。
  4. sorted(リスト)並べ替えた新しいリストを返すreverse=True で降順。リスト.sort() は元のリスト自体を書き換える。
  5. タプルは ( ) で作り変更できない。座標・設定値など「変えたくない組」に使う。for name, age in データ: のように分解して取り出せる。

現場使用例:CSVの1行を ["田中", "営業", "82"] として扱う、売上リストの合計 sum(sales)、ランキング上位3件 sorted(...)[:3]、緯度経度をタプルで固定。

items = ["りんご", "みかん", "ぶどう"]

print(items[0])     # りんご
print(items[-1])    # ぶどう
print(len(items))   # 3

items.append("もも")      # 末尾に追加
items.remove("みかん")    # 値を指定して削除
print(items)              # ['りんご', 'ぶどう', 'もも']

print(items[0:2])         # ['りんご', 'ぶどう'] スライス

nums = [5, 2, 9, 1]
print(sum(nums), max(nums))          # 17 9
print(sorted(nums, reverse=True))    # [9, 5, 2, 1]

point = (35.6, 139.7)   # タプルは後から変更できない

3基本ドリル(10問)

PY06-D01 fruits = ["りんご", "みかん", "ぶどう"] の最初最後の要素を、この順に1行ずつ出力せよ。 コーディング★☆☆無料
期待される結果

出力 == りんご / ぶどう(2行)

ヒント

先頭は [0]、末尾は [-1] で取り出せる。

模範解答
fruits = ["りんご", "みかん", "ぶどう"]
print(fruits[0])
print(fruits[-1])
解説

[-1] を使えば「要素が何個あっても末尾」が取れる。len(fruits) - 1 と書く必要はない。

PY06-D02 items = ["a", "b", "c", "d"] のとき items[2] の値はどれか。
A. "b" B. "c" C. "d" D. エラーになる
選択★☆☆無料
期待される結果

解答 == B

ヒント

番号は0から数える。

模範解答
B
解説

0番が"a"、1番が"b"、2番が"c"。「2番目」と「番号2」は違うという点が初学者最大の混乱ポイント。

PY06-D03 nums = [1, 2, 3] の末尾に 4 を追加し、リスト全体を出力せよ。 コーディング★☆☆無料
期待される結果

出力 == [1, 2, 3, 4]

ヒント

append() を使う。

模範解答
nums = [1, 2, 3]
nums.append(4)
print(nums)
解説

append はリスト自体を書き換えるので、nums = nums.append(4) と書くと None が入ってしまう。代入しないのが正解。

PY06-D04 colors = ["赤", "青", "黄"] の要素数を出力するコードを完成させよ。 穴埋め★☆☆無料
コード
colors = ["赤", "青", "黄"]
print(____(colors))
期待される結果

出力 == 3

ヒント

個数を数える組み込み関数。

模範解答
print(len(colors))
解説

len() は文字列にも使える(文字数)。PY05の平均計算でも使った、最頻出の関数のひとつ。

PY06-D05 nums = [10, 20, 30, 40, 50] のとき nums[1:3] の結果はどれか。
A. [20, 30] B. [20, 30, 40] C. [10, 20, 30] D. [30, 40]
選択★☆☆無料
期待される結果

解答 == A

ヒント

開始は含む、終了は含まない。

模範解答
A
解説

番号1(20)から始まり、番号3(40)の手前まで。rangeと同じルールなので合わせて覚えると迷わない。

PY06-D06 scores = [72, 95, 61, 88] を大きい順に並べ替えて出力せよ。 コーディング★★☆無料
期待される結果

出力 == [95, 88, 72, 61]

ヒント

sorted() に reverse=True を渡す。

模範解答
scores = [72, 95, 61, 88]
print(sorted(scores, reverse=True))
解説

sorted() は新しいリストを返すので元の scores は無傷。元を直接並べ替えたいときは scores.sort(reverse=True)。

PY06-D07 items から "みかん" を削除するコードを完成させよ。 穴埋め★★☆無料
コード
items = ["りんご", "みかん", "ぶどう"]
items.____("みかん")
print(items)
期待される結果

出力 == ['りんご', 'ぶどう']

ヒント

「値を指定して」削除するメソッド。

模範解答
items.remove("みかん")
解説

remove はを指定、pop は番号を指定。同じ値が複数あると remove は最初の1つだけを消す。

PY06-D08 point = (10, 20) のとき point[0] = 99 を実行するとどうなるか。
A. 値が変更される B. TypeErrorになる C. 無視される D. 新しいタプルができる
選択★★☆無料
期待される結果

解答 == B

ヒント

タプルの最大の特徴は何か。

模範解答
B
解説

タプルは変更できないのが存在意義。「うっかり書き換えたくないデータ」に使うと、事故をエラーとして検出できる。

PY06-D09 nums = [12, 45, 7, 23] の合計最大値を、この順に1行ずつ出力せよ。 コーディング★★☆無料
期待される結果

出力 == 87 / 45(2行)

ヒント

sum() と max() を使えばループを書かなくてよい。

模範解答
nums = [12, 45, 7, 23]
print(sum(nums))
print(max(nums))
解説

PY05ではループで合計を出したが、リストなら sum() 一発。min() で最小値も取れる。既にある道具を使うのが実務では正しい。

PY06-D10 scores = [72, 95, 61, 88, 79] を大きい順に並べ、上位3件だけをリストとして出力せよ。 コーディング★★☆無料
期待される結果

出力 == [95, 88, 79]

ヒント

sorted した結果にスライスをつなげて書ける。

模範解答
scores = [72, 95, 61, 88, 79]
print(sorted(scores, reverse=True)[:3])
解説

並べ替え → 先頭を切り出すでランキング上位N件が1行で書ける。実務のランキング表示はほぼこの形。

4実践シナリオ(5問)

PY06-S01 【買い物リスト】items = ["牛乳", "卵", "パン"] に "バター" を追加し、"卵" を削除したうえで、番号付きで1行ずつ出力し、最後に「合計3点」と出力せよ。 コーディング★★☆無料
期待される結果

3行の番号付きリスト+最終行 合計3点

ヒント

append と remove を使ってから enumerate(items, 1) で回す。点数は len()。

模範解答
items = ["牛乳", "卵", "パン"]
items.append("バター")
items.remove("卵")

for i, item in enumerate(items, 1):
    print(f"{i}. {item}")

print(f"合計{len(items)}点")
解説

追加・削除で並びがどう変わるかを確認する問題。append は末尾に付くので「牛乳・パン・バター」の順になる。

PY06-S02 【成績表】names = ["佐藤", "鈴木", "高橋"]、scores = [82, 95, 67] の2本のリストがある。「佐藤:82点」の形式で3行出力し、最後に「平均:81.3点」と小数1桁で出力せよ。 コーディング★★☆無料
期待される結果

3行の成績+最終行 平均:81.3点

ヒント

enumerate(names) の番号 i を使って scores[i] を引く。平均は sum / len、表示は {x:.1f}。

模範解答
names = ["佐藤", "鈴木", "高橋"]
scores = [82, 95, 67]

for i, name in enumerate(names):
    print(f"{name}:{scores[i]}点")

average = sum(scores) / len(scores)
print(f"平均:{average:.1f}点")
解説

2本のリストを同じ順番で対応させる「並行リスト」。番号でひも付けるので順序がズレると壊れるのが弱点。次章の辞書でこの弱点を解消する。

PY06-S03 【売上ランキング】sales = [120, 340, 210, 450, 180](単位:万円)の上位3件を「1位:450万円」の形式で出力せよ。 コーディング★★☆無料
期待される結果

3行。1位:450万円 / 2位:340万円 / 3位:210万円

ヒント

sorted(..., reverse=True)[:3] で上位3件を作り、enumerate(top3, 1) で順位を振る。

模範解答
sales = [120, 340, 210, 450, 180]
top3 = sorted(sales, reverse=True)[:3]

for i, s in enumerate(top3, 1):
    print(f"{i}位:{s}万円")
解説

D10の「上位N件」とPY05の enumerate を組み合わせた形。ランキング表示はこの2手で必ず作れる。

PY06-S04 【注文の集計】orders = ["A", "B", "A", "C", "B", "A"] から、登場した順を保ったまま商品を重複なく取り出し、それぞれの件数を「A:3件」の形式で出力せよ。 コーディング★★★無料
期待される結果

3行。A:3件 / B:2件 / C:1件

ヒント

空のリストを用意し、not in で「まだ入っていなければ append」する。件数は orders.count(値)。

模範解答
orders = ["A", "B", "A", "C", "B", "A"]

unique = []
for o in orders:
    if o not in unique:
        unique.append(o)

for u in unique:
    print(f"{u}:{orders.count(u)}件")
解説

not in で重複を防ぐのは定番テクニック。count() は指定した値の個数を返す。次章の集合(set)や辞書を使うともっと短く書けるようになる。

PY06-S05 【駅データの抽出】stations = [("東京", 35.68), ("大阪", 34.69), ("札幌", 43.06)] から緯度が35以上の駅を「東京(緯度35.68)」の形式で出力し、最後に「該当:2件」と出力せよ。 コーディング★★★無料
期待される結果

該当2件を出力後、最終行 該当:2件

ヒント

for name, lat in stations: と書けばタプルを2つの変数に分解して受け取れる。

模範解答
stations = [("東京", 35.68), ("大阪", 34.69), ("札幌", 43.06)]

count = 0
for name, lat in stations:
    if lat >= 35:
        print(f"{name}(緯度{lat})")
        count += 1

print(f"該当:{count}件")
解説

タプルのリストは表形式データの定番表現。CSVを読み込むとこの形になる。for での分解(アンパック)を覚えると一気に実務的なコードが書ける。

5仕上げ課題

PY06-FINAL 【在庫レポート】商品名と在庫数の2本のリストから、明細と集計を出力するスクリプトを書け。
products = ["ボールペン", "ノート", "消しゴム", "ファイル", "付箋"]
stocks = [120, 8, 45, 3, 67]
threshold = 10


仕様:
① 各商品を「1. ボールペン:120個」の形式で出力。在庫が threshold 未満の商品は末尾に「 ⚠発注」を付ける
② 明細の後に --- の行を出す
③ 総在庫と品目数を1行で出す
④ 要発注の品目数と商品名(読点区切り)を1行で出す
⑤ 最も在庫が多い商品とその数を1行で出す

出力仕様(9行):
=== 在庫レポート ===
1. ボールペン:120個
2. ノート:8個 ⚠発注
3. 消しゴム:45個
4. ファイル:3個 ⚠発注
5. 付箋:67個
---
総在庫:243個 / 品目数:5
要発注:2品目(ノート、ファイル)
最多在庫:ボールペン(120個)
期待される結果

出力10行が完全一致

ヒント

enumerate(products) の番号 i で stocks[i] を引く。要発注の商品名は空のリストに append で集め、表示は "、".join(リスト) でつなぐ。最多在庫は stocks.index(max(stocks)) で番号を求めれば products から名前が引ける。

模範解答
products = ["ボールペン", "ノート", "消しゴム", "ファイル", "付箋"]
stocks = [120, 8, 45, 3, 67]
threshold = 10

print("=== 在庫レポート ===")

low = []
for i, name in enumerate(products):
    stock = stocks[i]

    if stock < threshold:
        low.append(name)
        mark = " ⚠発注"
    else:
        mark = ""

    print(f"{i + 1}. {name}:{stock}個{mark}")

best_index = stocks.index(max(stocks))

print("---")
print(f"総在庫:{sum(stocks)}個 / 品目数:{len(products)}")
print(f"要発注:{len(low)}品目({'、'.join(low)})")
print(f"最多在庫:{products[best_index]}({max(stocks)}個)")
解説

2本の並行リストを番号でひも付けながら、1回のループで明細と集計を同時に作るのが要点。index() は「値から番号を逆引き」する道具で、max() と組み合わせると「最大値の持ち主」が特定できる。ここまで書ければ、CSVを読み込んで在庫アラートを出す実務スクリプトの骨格が完成している。