Python:リストとタプル
1学習の目的
- リストで複数のデータをまとめて持ち、取り出し・追加・削除・並べ替えができるようになる。変数を10個作る代わりにリスト1本で扱えるようになる。
- スライスや sum / max / sorted を使った集計・ランキング処理を書けるようになる。CSVや売上データの加工はすべてリスト操作の組み合わせでできている。
2基礎解説
| やりたいこと | 書き方 | 結果・意味 |
|---|---|---|
| リストを作る | items = ["a", "b", "c"] | 順序あり・後から変更できる |
| 取り出す | items[0] / items[-1] | 先頭は0番、末尾は-1 |
| 一部を切り出す | items[1:3] | 1番以上3番未満(終了は含まない) |
| 変更できない並び | point = (35.6, 139.7) | タプル。作った後は書き換え不可 |
- 番号は0始まり。3個のリストの番号は 0,1,2。末尾は items[-1]、個数は len(items)。
- 追加は append(値)、削除は remove(値) または pop(番号)。
- スライス items[1:4] は「1以上4未満」。rangeと同じで終わりは含まない。items[:3] で先頭3件。
- sorted(リスト) は並べ替えた新しいリストを返す。reverse=True で降順。リスト.sort() は元のリスト自体を書き換える。
- タプルは ( ) で作り変更できない。座標・設定値など「変えたくない組」に使う。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問)
出力 == りんご / ぶどう(2行)
先頭は [0]、末尾は [-1] で取り出せる。
fruits = ["りんご", "みかん", "ぶどう"] print(fruits[0]) print(fruits[-1])
[-1] を使えば「要素が何個あっても末尾」が取れる。len(fruits) - 1 と書く必要はない。
A. "b" B. "c" C. "d" D. エラーになる 選択★☆☆無料
解答 == B
番号は0から数える。
B
0番が"a"、1番が"b"、2番が"c"。「2番目」と「番号2」は違うという点が初学者最大の混乱ポイント。
出力 == [1, 2, 3, 4]
append() を使う。
nums = [1, 2, 3] nums.append(4) print(nums)
append はリスト自体を書き換えるので、nums = nums.append(4) と書くと None が入ってしまう。代入しないのが正解。
colors = ["赤", "青", "黄"] print(____(colors))
出力 == 3
個数を数える組み込み関数。
print(len(colors))
len() は文字列にも使える(文字数)。PY05の平均計算でも使った、最頻出の関数のひとつ。
A. [20, 30] B. [20, 30, 40] C. [10, 20, 30] D. [30, 40] 選択★☆☆無料
解答 == A
開始は含む、終了は含まない。
A
番号1(20)から始まり、番号3(40)の手前まで。rangeと同じルールなので合わせて覚えると迷わない。
出力 == [95, 88, 72, 61]
sorted() に reverse=True を渡す。
scores = [72, 95, 61, 88] print(sorted(scores, reverse=True))
sorted() は新しいリストを返すので元の scores は無傷。元を直接並べ替えたいときは scores.sort(reverse=True)。
items = ["りんご", "みかん", "ぶどう"]
items.____("みかん")
print(items)
出力 == ['りんご', 'ぶどう']
「値を指定して」削除するメソッド。
items.remove("みかん")
remove は値を指定、pop は番号を指定。同じ値が複数あると remove は最初の1つだけを消す。
A. 値が変更される B. TypeErrorになる C. 無視される D. 新しいタプルができる 選択★★☆無料
解答 == B
タプルの最大の特徴は何か。
B
タプルは変更できないのが存在意義。「うっかり書き換えたくないデータ」に使うと、事故をエラーとして検出できる。
出力 == 87 / 45(2行)
sum() と max() を使えばループを書かなくてよい。
nums = [12, 45, 7, 23] print(sum(nums)) print(max(nums))
PY05ではループで合計を出したが、リストなら sum() 一発。min() で最小値も取れる。既にある道具を使うのが実務では正しい。
出力 == [95, 88, 79]
sorted した結果にスライスをつなげて書ける。
scores = [72, 95, 61, 88, 79] print(sorted(scores, reverse=True)[:3])
並べ替え → 先頭を切り出すでランキング上位N件が1行で書ける。実務のランキング表示はほぼこの形。
4実践シナリオ(5問)
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 は末尾に付くので「牛乳・パン・バター」の順になる。
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本のリストを同じ順番で対応させる「並行リスト」。番号でひも付けるので順序がズレると壊れるのが弱点。次章の辞書でこの弱点を解消する。
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手で必ず作れる。
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)や辞書を使うともっと短く書けるようになる。
該当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仕上げ課題
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を読み込んで在庫アラートを出す実務スクリプトの骨格が完成している。