1.

Python リスト作成完全ガイド(リテラル・内包表記・range・ネスト)

編集
この記事の要点
  • リストは [1, 2, 3] / list() / list(range(N)) で作る
  • リスト内包表記 [x**2 for x in range(10)] が定番
  • 同一要素 N 個 [0] * 10。ただし [[0]*3]*3 は同じ list を 3 回参照する罠
  • ネストしたリストは [[0]*3 for _ in range(3)] で安全に作成
  • 追加: append (末尾 1 件) / extend (反復可能オブジェクトを連結) / insert (位置指定)

リストとは

Python のリストは順序付き、可変、異なる型の要素を混在可能なシーケンスです。最もよく使う Python 標準のコレクション型で、用途に応じた多彩な作成方法があります。

1. リテラル [...]

# 基本
nums = [1, 2, 3, 4, 5]
fruits = ['apple', 'banana', 'cherry']
mixed = [1, 'two', 3.0, True, None]   # 混在 OK
empty = []

# ネスト
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

# 改行は許される (末尾カンマも OK)
config = [
    'option_a',
    'option_b',
    'option_c',
]

2. list() コンストラクタ

list()                # []
list('hello')         # ['h', 'e', 'l', 'l', 'o']
list((1, 2, 3))       # [1, 2, 3]
list({1, 2, 3})       # [1, 2, 3] (順序は不定)
list({'a': 1, 'b': 2})  # ['a', 'b']  (キーが返る)
list(range(5))        # [0, 1, 2, 3, 4]

# ジェネレータからリスト化
def gen():
    yield 1
    yield 2
list(gen())           # [1, 2]

3. リスト内包表記 (List Comprehension)

もっとも Python らしいリスト作成方法。map / filter より高速で読みやすいとされ、PEP 8 でも推奨。

# 基本: [式 for 変数 in 反復可能オブジェクト]
squares = [x ** 2 for x in range(10)]
# → [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

# 条件付き (filter)
evens = [x for x in range(20) if x % 2 == 0]
# → [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

# 三項演算子 (map + 変換)
labels = ['偶' if x % 2 == 0 else '奇' for x in range(5)]
# → ['偶', '奇', '偶', '奇', '偶']

# 二重ループ
pairs = [(i, j) for i in range(3) for j in range(3) if i != j]

# 二次元リストのフラット化
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flat = [v for row in matrix for v in row]
# → [1, 2, 3, 4, 5, 6, 7, 8, 9]

# 文字列処理
upper = [w.upper() for w in ['apple', 'banana', 'cherry']]
# → ['APPLE', 'BANANA', 'CHERRY']

4. 同一要素 N 個 [x] * N

zeros = [0] * 10            # [0,0,0,0,0,0,0,0,0,0]
nones = [None] * 5          # [None]*5
buf = [''] * 100            # 文字列バッファ初期化

# 要素がスカラー (不変) なら安全
zeros[0] = 99               # OK → [99, 0, 0, ...]

5. ネストリスト作成の罠 ([[0]*3]*3 はバグ)

もっとも有名な Python の落とし穴。* 3同じオブジェクトを 3 回繰り返すため、内側 list がすべて同じ参照になります。

# ❌ 罠
matrix = [[0] * 3] * 3
# → [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
# 一見正しそう…

matrix[0][0] = 99
# → [[99, 0, 0], [99, 0, 0], [99, 0, 0]]   ← 全行が変わる!

# 内部的に: matrix[0] is matrix[1] is matrix[2]  → True

# ✅ 正解1: リスト内包表記でループごとに新規 list 生成
matrix = [[0] * 3 for _ in range(3)]
matrix[0][0] = 99
# → [[99, 0, 0], [0, 0, 0], [0, 0, 0]]   ← 0 行目だけ

# ✅ 正解2: NumPy
import numpy as np
matrix = np.zeros((3, 3))

6. 連結 + と繰り返し *

[1, 2] + [3, 4]      # [1, 2, 3, 4]
[0] * 5              # [0, 0, 0, 0, 0]

# 既存リストへの破壊的連結
a = [1, 2]
a += [3, 4]          # a.extend([3, 4]) と同じ → [1, 2, 3, 4]

# 大量連結はパフォーマンス注意 (毎回新規 list)
result = []
for i in range(10000):
    result = result + [i]   # ❌ 遅い

# ✅ append / extend を使う
result = []
for i in range(10000):
    result.append(i)

7. 追加・削除メソッド

メソッド動作計算量
list.append(x)末尾に 1 要素追加O(1) 償却
list.extend(iter)反復可能オブジェクトを連結O(K)
list.insert(i, x)i 番目に x を挿入O(N)
list.remove(x)最初に見つかった x を削除O(N)
list.pop()末尾を取り出して削除O(1)
list.pop(i)i 番目を取り出して削除O(N)
del lst[i]i 番目を削除O(N)
list.clear()全削除O(N)
lst = [1, 2, 3]
lst.append(4)         # [1, 2, 3, 4]
lst.extend([5, 6])    # [1, 2, 3, 4, 5, 6]
lst.insert(0, 0)      # [0, 1, 2, 3, 4, 5, 6]

lst.remove(3)         # [0, 1, 2, 4, 5, 6]   存在しないと ValueError
last = lst.pop()      # last=6, lst=[0, 1, 2, 4, 5]
first = lst.pop(0)    # first=0, lst=[1, 2, 4, 5]
del lst[1]            # [1, 4, 5]

# ⚠️ append と extend を間違えると痛い
a = [1, 2]
a.append([3, 4])      # → [1, 2, [3, 4]]   入れ子になる
a = [1, 2]
a.extend([3, 4])      # → [1, 2, 3, 4]     展開される

8. スライス

lst = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

lst[2:5]      # [2, 3, 4]
lst[:3]       # [0, 1, 2]
lst[7:]       # [7, 8, 9]
lst[-3:]      # [7, 8, 9]
lst[::2]      # [0, 2, 4, 6, 8]   ステップ
lst[::-1]     # [9, 8, ..., 0]    反転

# コピー (浅いコピー)
copy = lst[:]
copy = list(lst)
copy = lst.copy()

# スライス代入で部分置換
lst[2:5] = [99, 99]    # → [0, 1, 99, 99, 5, 6, 7, 8, 9]

9. range / itertools の活用

list(range(10))                 # 0..9
list(range(1, 11))              # 1..10
list(range(0, 20, 2))           # 偶数 0..18
list(range(10, 0, -1))          # 10..1

# itertools
from itertools import repeat, chain, product, combinations

list(repeat('x', 5))            # ['x', 'x', 'x', 'x', 'x']
list(chain([1, 2], [3, 4]))     # [1, 2, 3, 4]
list(product([0, 1], repeat=2)) # [(0,0), (0,1), (1,0), (1,1)]
list(combinations([1, 2, 3], 2))# [(1, 2), (1, 3), (2, 3)]

FAQ

Q: list と array、tuple の使い分けは?
A: 通常は list。変更しないなら tuple数値のみで高速化したいなら NumPy 配列 または array.array

Q: append と insert(0, x) どちらが速い?
A: append は O(1)、insert(0, x) は O(N)。先頭挿入を多用するなら collections.deque

Q: list.copy()copy.deepcopy() の違いは?
A: 前者は浅いコピー (内側 list は共有)、後者は再帰的に完全コピー。ネスト構造を変えたいなら deepcopy。

編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. リストの作成
  2. 要素の参照
  3. リストへの要素追加(append / extend / insert / += / slice 代入)
  4. リスト要素の更新
  5. 要素の削除
  6. リスト要素数の取得

最近更新/作成されたページ