- Python
Python リスト 操作 一覧|全メソッド逆引きと3.14実行結果
Pythonのリスト(list)とは、複数の値を順番つきでまとめて持ち、あとから追加・削除・並べ替えができる入れ物です。 操作は、append や sort などの11個のメソッドと、len・sorted・スライスなどの組み込み関数・演算の組み合わせで書けます。
この記事では、リスト操作を「やりたいこと→コード→実行結果」の逆引き表でまとめ、全コードを Python 3.14.7(uvで導入)で実行した出力つきで解説します。さらに、x = x.sort() で None になる、[[0]*3]*3 で全行が変わる、といったつまずきやすい動きの実例と、list.insert(0, x) と deque の速度の実測、公式Wikiに基づく計算量の目安表も載せています。
Python リスト操作の早見表(逆引き)
| やりたいこと | コード | 結果(a = [5, 3, 8, 1] など) |
元を変える |
|---|---|---|---|
| 末尾に1つ追加 | a.append(x) |
None を返す |
する |
| 末尾に複数追加 | a.extend([x, y]) |
None |
する |
| 位置を指定して追加 | a.insert(i, x) |
None |
する |
| 値を指定して削除 | a.remove(x) |
最初の1件だけ | する |
| 位置を指定して取り出す | a.pop() / a.pop(i) |
取り出した値 | する |
| 位置・範囲で削除 | del a[i] / del a[1:3] |
— | する |
| 全部消す | a.clear() |
None |
する |
| 位置を探す | a.index(x) |
無ければ ValueError |
しない |
| 個数を数える | a.count(x) |
整数 | しない |
| 並べ替え(元を変える) | a.sort() / a.sort(reverse=True) |
None |
する |
| 並べ替えた新しいリスト | sorted(a) |
[1, 3, 5, 8] |
しない |
| 逆順(元を変える) | a.reverse() |
None |
する |
| 逆順の新しいリスト | a[::-1] / list(reversed(a)) |
[1, 8, 3, 5] |
しない |
| コピー | a.copy() / a[:] / copy.deepcopy(a) |
新しいリスト | しない |
| 要素数 | len(a) |
4 |
しない |
| 含むか | x in a / x not in a |
True / False |
しない |
| 連結・繰り返し | a + b / [0] * 3 |
新しいリスト | しない |
| 一部を取り出す | a[1:3] / a[-1] |
[3, 8] / 1 |
しない |
| 番号つきで回す | enumerate(a, start=1) |
(1, 5), (2, 3)… |
しない |
| 2つを組にする | zip(names, prices) |
(名, 価格) の組 |
しない |
| 最小・最大・合計 | min(a) / max(a) / sum(a) |
1 / 8 / 17 |
しない |
| 1つでも/全部満たすか | any(...) / all(...) |
True / False |
しない |
| 変換して新しいリスト | [f(x) for x in a] |
内包表記 | しない |
| 重複を除く(順序維持) | list(dict.fromkeys(a)) |
最初の出現順 | しない |
| N件ずつに分ける | itertools.batched(a, n) |
タプルの組(3.12以降) | しない |
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「Python リスト 操作 一覧|全メソッド逆引きと3.14実行結果」
リストのメソッド全11個を実行して確認
list のメソッドは append・extend・insert・remove・pop・clear・index・count・sort・reverse・copy の11個です(Python公式ドキュメント「データ構造」)。index・count・copy・pop 以外は値を返さず(None)、元のリストを直接変更します。
items = ["pen", "note"]
items.append("tape"); print(items)
items.extend(["clip", "glue"]); print(items)
items.insert(1, "ruler"); print(items)
items.remove("note"); print(items)
last = items.pop(); print(last, items)
first = items.pop(0); print(first, items)
print(items.index("tape"), items.count("tape"))
nums = [3, 1, 2]; nums.sort(); print(nums)
nums.sort(reverse=True); print(nums)
nums.reverse(); print(nums)
c = nums.copy(); c.append(99); print(nums, c)
nums.clear(); print(nums)
['pen', 'note', 'tape']
['pen', 'note', 'tape', 'clip', 'glue']
['pen', 'ruler', 'note', 'tape', 'clip', 'glue']
['pen', 'ruler', 'tape', 'clip', 'glue']
glue ['pen', 'ruler', 'tape', 'clip']
pen ['ruler', 'tape', 'clip']
1 1
[1, 2, 3]
[3, 2, 1]
[1, 2, 3]
[1, 2, 3] [1, 2, 3, 99]
[]
| メソッド | 戻り値 | 見つからない・空のとき |
|---|---|---|
append(x) / extend(it) / insert(i, x) |
None |
— |
remove(x) |
None |
ValueError |
pop([i]) |
取り出した値 | IndexError |
clear() / sort() / reverse() |
None |
— |
index(x[, start[, end]]) |
位置(整数) | ValueError |
count(x) |
個数 | 0 |
copy() |
浅いコピー | — |
append と extend の違いは、append([1, 2]) がリストを1つの要素として足すのに対し、extend([1, 2]) は中身を1つずつ足す点です。
見つからないときのエラー
["a"].remove("z") # ValueError: list.remove(x): x not in list
["a"].index("z") # ValueError: list.index(x): x not in list
[].pop() # IndexError: pop from empty list
[1][5] # IndexError: list index out of range
[1][5:9] # [] (スライスは範囲外でもエラーにならない)
sorted([1, "a"]) # TypeError: '<' not supported between instances of 'str' and 'int'
エラーを避けたいときは、先に if x in a: で確かめてから remove や index を呼びます。
関連する組み込み関数・演算を実行して確認
a = [5, 3, 8, 1]
print(len(a), 8 in a, 7 not in a)
print(a + [0], [0] * 3)
print(a[1:3], a[::-1], a[-1])
del a[0]; print(a)
print(sorted(a), list(reversed(a)), a)
for i, v in enumerate(["A", "B"], start=1): print(i, v)
print(list(zip(["pen", "note"], [120, 300])))
print(min(a), max(a), sum(a))
print(any(x > 5 for x in a), all(x > 0 for x in a))
4 True True
[5, 3, 8, 1, 0] [0, 0, 0]
[3, 8] [1, 8, 3, 5] 1
[3, 8, 1]
[1, 3, 8] [1, 8, 3] [3, 8, 1]
1 A
2 B
[('pen', 120), ('note', 300)]
1 8 12
True True
スライスで取り出す・置き換える・消す
スライス a[開始:終了:間隔] は「開始は含み、終了は含まない」範囲です。 代入や del と組み合わせると、範囲ごと置き換え・削除ができます。
a = [1, 2, 3, 4, 5]
a[1:3] = ["x"]; print(a) # 2要素を1要素に置き換え
a = [1, 2, 3, 4, 5]
a[::2] = [0, 0, 0]; print(a) # 1つおきに置き換え(個数を合わせる)
del a[::2]; print(a) # 1つおきに削除
x, *rest = [10, 20, 30]; print(x, rest) # アンパック
[1, 'x', 4, 5]
[0, 2, 0, 4, 0]
[2, 4]
10 [20, 30]
間隔つきスライス(a[::2])への代入は個数が一致しないとエラーになります。 実際に2要素の範囲へ3要素を入れると ValueError: attempt to assign sequence of size 3 to extended slice of size 2 になりました。
zip は短い方に合わせる
print(list(zip([1, 2, 3], ["a", "b"])))
list(zip([1, 2, 3], ["a", "b"], strict=True))
[(1, 'a'), (2, 'b')]
ValueError: zip() argument 2 is shorter than argument 1
長さの違いを見落としたくないときは strict=True(3.10以降)を付けます。 空のリストに max() を使うとエラーになるので、max([], default=0) のように既定値を渡すと安全です。
x = x.sort() で None になる罠
sort() は元のリストを並べ替えて None を返すため、結果を代入すると変数が None になります。
x = [3, 1, 2]
x = x.sort()
print(x)
x.append(1)
None
AttributeError: 'NoneType' object has no attribute 'append'
直し方は2通りです。
x = [3, 1, 2]
x.sort() # 1. 代入しない(元を変える)
y = sorted(x) # 2. sorted で新しいリストを受け取る(元は残る)
同じ罠は append・extend・insert・reverse・remove・clear にもあります。 「元を変えるメソッドは None を返す」と覚えておくと迷いません。
sort と sorted の違い・key と reverse の使い方
a.sort() |
sorted(a) |
|
|---|---|---|
| 元のリスト | 変わる | 変わらない |
| 戻り値 | None |
新しいリスト |
| 使える対象 | リストだけ | タプル・集合・辞書など何でも |
| 引数 | key・reverse |
key・reverse |
key には「並べ替えの基準を返す関数」を渡します。 複数条件はタプルで返し、数値の降順は - を付けると1回で書けます。
members = [
{"name": "佐藤", "age": 31, "score": 82},
{"name": "鈴木", "age": 25, "score": 95},
{"name": "高橋", "age": 31, "score": 77},
]
print([m["name"] for m in sorted(members, key=lambda m: m["score"], reverse=True)])
print([m["name"] for m in sorted(members, key=lambda m: (-m["age"], m["score"]))])
from operator import itemgetter
print([m["name"] for m in sorted(members, key=itemgetter("age", "score"))])
words = ["banana", "apple", "Cherry"]
print(sorted(words), sorted(words, key=str.lower))
print(sorted(["10", "9", "100"]), sorted(["10", "9", "100"], key=int))
['鈴木', '佐藤', '高橋']
['高橋', '佐藤', '鈴木']
['鈴木', '高橋', '佐藤']
['Cherry', 'apple', 'banana'] ['apple', 'banana', 'Cherry']
['10', '100', '9'] ['9', '10', '100']
- 大文字は小文字より前に並びます(文字コード順)。大文字小文字を区別しないなら
key=str.lower。 - 数字の文字列は辞書順になるので、数値として並べるなら
key=int。 - Pythonの並べ替えは安定ソート(同じ値の元の順序を保つ)です。
コピー:代入・浅いコピー・深いコピーの違い
b = a はコピーではなく、同じリストに別の名前を付けるだけです。 copy() や a[:] は外側だけを新しくする「浅いコピー」で、中のリストは共有されます。
import copy
a = [[1, 2], [3, 4]]
b = a # 代入
c = a.copy() # 浅いコピー
d = copy.deepcopy(a) # 深いコピー
a[0].append(99)
a.append([5])
print("a", a); print("b", b); print("c", c); print("d", d)
print(b is a, c is a, c[0] is a[0], d[0] is a[0])
a [[1, 2, 99], [3, 4], [5]]
b [[1, 2, 99], [3, 4], [5]]
c [[1, 2, 99], [3, 4]]
d [[1, 2], [3, 4]]
True False True False
| 方法 | 外側の追加・削除 | 中身(入れ子)の変更 | 用途 |
|---|---|---|---|
b = a |
共有 | 共有 | 同じものを指したいとき |
a.copy() / a[:] / list(a) |
独立 | 共有 | 中身が数値・文字列だけのとき |
copy.deepcopy(a) |
独立 | 独立 | 入れ子のリスト・辞書 |
[[0]*3]*3 で全行が変わる罠
掛け算(*)による繰り返しは、同じ内側のリストを3回並べるだけです。
grid = [[0] * 3] * 3
grid[0][0] = 1
print(grid)
grid = [[0] * 3 for _ in range(3)]
grid[0][0] = 1
print(grid)
[[1, 0, 0], [1, 0, 0], [1, 0, 0]]
[[1, 0, 0], [0, 0, 0], [0, 0, 0]]
2次元リストは内包表記で1行ずつ新しく作ると、行ごとに独立します。 [0] * 3 のように中身が数値なら * で問題ありません。
内包表記で変換・絞り込み
内包表記 [式 for 変数 in リスト if 条件] は、for文と append を1行にまとめた書き方です。
prices = [120, 980, 450, 3000]
print([round(p * 1.1) for p in prices if p >= 500]) # 絞り込み+変換
print(["高" if p >= 1000 else "低" for p in prices]) # 条件で値を変える
print([(r, c) for r in range(2) for c in range(2)]) # 二重ループ
[1078, 3300]
['低', '低', '低', '高']
[(0, 0), (0, 1), (1, 0), (1, 1)]
if の位置で意味が変わります。 後ろの if は「絞り込み」、前の A if 条件 else B は「値の切り替え」です。10万件で比べると、for文+append が10回で44.7ミリ秒、内包表記が34.2ミリ秒でした(Python 3.14.7、timeit の最小値)。
実務でよく使うリスト操作
重複を除く(順序を保つ)
tags = ["python", "sql", "python", "git", "sql"]
print(list(dict.fromkeys(tags))) # 最初に出た順を保つ
print(sorted(set(tags))) # 順序は捨てて並べ替え
rows = [{"id": 1, "v": "a"}, {"id": 2, "v": "b"}, {"id": 1, "v": "c"}]
seen, uniq = set(), []
for r in rows:
if r["id"] not in seen:
seen.add(r["id"]); uniq.append(r)
print(uniq)
['python', 'sql', 'git']
['git', 'python', 'sql']
[{'id': 1, 'v': 'a'}, {'id': 2, 'v': 'b'}]
set は順序を保証しないため、順序を残したいときは dict.fromkeys を使います(辞書は挿入順を保つ仕様)。辞書のように set に入れられない要素は、キーだけを set で管理します。
入れ子を平坦にする
import itertools
nested = [[1, 2], [3], [], [4, 5]]
print([x for row in nested for x in row])
print(list(itertools.chain.from_iterable(nested)))
def flatten(xs): # 深さが不定のとき
for x in xs:
if isinstance(x, list):
yield from flatten(x)
else:
yield x
print(list(flatten([1, [2, [3, [4]], 5]])))
[1, 2, 3, 4, 5]
[1, 2, 3, 4, 5]
[1, 2, 3, 4, 5]
N件ずつに分割する(itertools.batched)
Python 3.12で追加された itertools.batched を使うと、N件ずつのかたまりに分けられます。 3.13からは strict=True で端数をエラーにできます。
from itertools import batched
ids = list(range(1, 11))
print(list(batched(ids, 4)))
print([list(b) for b in batched(ids, 4)])
list(batched(ids, 4, strict=True))
[(1, 2, 3, 4), (5, 6, 7, 8), (9, 10)]
[[1, 2, 3, 4], [5, 6, 7, 8], [9, 10]]
ValueError: batched(): incomplete batch
3.11以前ではスライスで同じ結果になります:[ids[i:i + 4] for i in range(0, len(ids), 4)]。
その他の便利な操作
from collections import Counter
import bisect, itertools
print(Counter(["pen", "note", "pen"]).most_common(1)) # 最頻値
s = [10, 20, 30]; bisect.insort(s, 25); print(s) # 並びを保って挿入
print(list(itertools.pairwise([1, 4, 9]))) # 隣り合う組
print([1, 2] < [1, 3], [2] > [1, 9]) # 先頭から順に比較
[('pen', 2)]
[10, 20, 25, 30]
[(1, 4), (4, 9)]
True True
計算量の目安と速度の実測
リストは「末尾の追加・削除と番号でのアクセスが速く、先頭への挿入・削除と in 検索は件数に比例して遅くなる」データ構造です。 公式Wiki「TimeComplexity」(CPython)の表から、よく使う操作を抜き出しました。
| 操作 | 計算量 | メモ |
|---|---|---|
a[i] / a[i] = x / len(a) |
O(1) | 件数に関係なく一定 |
append(x) / pop() |
O(1) | 末尾の操作 |
pop(0) / insert(0, x) / del a[i] |
O(n) | 後ろの要素をずらす |
x in a / index / count / remove |
O(n) | 先頭から順に探す |
extend(b) / a[i:j] |
O(k) | k は追加・取り出す件数 |
sort() / sorted() |
O(n log n) | |
min / max / sum |
O(n) |
10万件で実測すると(Python 3.14.7、timeit で3回の最小値)、差がはっきり出ました。
| 処理(10万回) | 時間 |
|---|---|
list.append(x) |
3.2 ms |
list.insert(0, x) |
1,134.7 ms |
deque.appendleft(x) |
4.1 ms |
list.pop(0) |
1,000.8 ms |
deque.popleft() |
4.0 ms |
99_999 in list(10万件、1,000回) |
756.43 ms |
99_999 in set(10万件、1,000回) |
0.036 ms |
先頭の出し入れが多いなら collections.deque、in の検索が多いなら set に変えると、処理時間が大きく変わります。
リスト・タプル・array・dequeの使い分け
| 型 | 変更 | 得意なこと | 100万件の sys.getsizeof |
|---|---|---|---|
list |
できる | 汎用。末尾の追加、番号アクセス | 8,000,056 バイト |
tuple |
できない | 固定の組、辞書のキー、関数の戻り値 | 8,000,048 バイト |
array.array("i") |
できる | 同じ型の数値を省メモリで持つ | 4,000,080 バイト |
collections.deque |
できる | 両端の追加・削除(キュー) | — |
※ sys.getsizeof は入れ物自体の大きさで、中の整数オブジェクトは含みません(array は値を直接持つため小さくなります)。
迷ったら list、変更しない組は tuple、両端の出し入れは deque、大量の数値計算はNumPy を選ぶのが目安です。
よくある質問
Q. リストの末尾の要素を取り出すには?
A. 取り出すだけなら a[-1]、取り出して削除するなら a.pop() です。空のリストだと IndexError になるので、if a: で確認してから使います。
Q. ループ中に要素を削除するとおかしくなります。
A. ループ中のリストを変更すると、要素がずれて飛ばされることがあります。 a = [x for x in a if 条件] で新しいリストを作るのが確実です。
Q. 2つのリストの共通部分や差分を取るには?
A. 順序が不要なら set(a) & set(b)(共通)、set(a) - set(b)(差分) です。順序を保つなら [x for x in a if x in set_b] のように、比較先だけ set にします。
Q. += と extend は同じですか?
A. リストに対する a += b は a.extend(b) と同じく元のリストを変更します。 a = a + b は新しいリストを作るため、別名(b = a など)で参照している側には反映されません。
まとめ
- リストのメソッドは11個。元を変えるメソッドは
Noneを返すのでx = x.sort()と書かない - 並べ替えは元を残すなら
sorted、変えるならsort。基準はkey、降順はreverse=True copy()は浅いコピー。入れ子ならcopy.deepcopy、2次元は内包表記で行ごとに作る- 重複除去は
list(dict.fromkeys(a))、分割はitertools.batched(3.12以降) - 先頭の出し入れは
deque、大量のin検索はsetに変えると速い - 範囲外でもスライスはエラーにならず、添字アクセスは
IndexError
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「Python リスト 操作 一覧|全メソッド逆引きと3.14実行結果」
株式会社RJCでは、基本の書き方も実際に動かして確かめ、その結果をプロジェクトの中で仲間と共有しています。こうした知識を共有しながら、日々技術を磨いています。
株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。
WE ARE HIRING
RJCで一緒に開発しながら、
成長を楽しみませんか?
RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!
- 127日年間休日
- 12時間平均残業時間
- 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!
ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。