- Python
Pythonリストに追加|append・extend・insertの違い早見表
Pythonのリストに要素を追加するには、1個なら append、複数まとめてなら extend、位置を決めて入れるなら insert を使います。 元のリストを残したまま新しいリストを作りたいときは、+ 演算子かアンパック([*a, *b])を選びます。この5〜6種類は見た目が似ていますが、「何個ずつ入るか」「元のリストが書き換わるか」「戻り値が何か」の3点がそれぞれ違います。
この記事では、その3点を1枚の早見表にまとめたうえで、すべてのコードを Python 3.13.7 と 3.14.7 で実際に動かした結果を載せています。lst = lst.append(x) で None になる、append にリストを渡して入れ子になる、extend に文字列を渡して1文字ずつ入る、という3つのつまずきもエラー文つきで再現し、timeit による速度の実測値と、どれを選ぶかの判断表まで用意しました。コードはそのままコピーして動かせます。
リストに追加する方法の早見表
まず結論です。「追加単位」「元のリストが変わるか」「戻り値」の3列を見れば、ほとんどの疑問が解決します。
| 書き方 | 追加単位 | 元のリスト | 戻り値 | 実行後(a = [1, 2, 3] のとき) |
|---|---|---|---|---|
a.append(4) |
1個(渡したものをそのまま1要素として) | 変わる | None | [1, 2, 3, 4] |
a.extend([4, 5]) |
複数(イテラブルの中身を1個ずつ) | 変わる | None | [1, 2, 3, 4, 5] |
a.insert(1, 99) |
1個(指定位置の前に) | 変わる | None | [1, 99, 2, 3] |
b = a + [4, 5] |
複数(リスト同士の結合) | 変わらない | 新しいリスト | a は [1, 2, 3]、b は [1, 2, 3, 4, 5] |
a += [4, 5] |
複数(extend と同じ動き) | 変わる | 式ではないので値なし | [1, 2, 3, 4, 5] |
c = [*a, *b, 5] |
複数(好きな順に並べて展開) | 変わらない | 新しいリスト | a はそのまま |
a[1:1] = [7, 8] |
複数(指定位置にまとめて挿入) | 変わる | 式ではないので値なし | [1, 7, 8, 2, 3] |
目的から選ぶときは次の表が便利です。
| やりたいこと | 使う書き方 |
|---|---|
| 末尾に1個追加する | a.append(x) |
| 末尾に複数まとめて追加する | a.extend(items) または a += items |
| 先頭や途中に1個入れる | a.insert(i, x) |
| 途中に複数まとめて入れる | a[i:i] = items |
| 元のリストを残して結合する | a + b または [*a, *b] |
| 3つ以上のリストを1つにする | [*a, *b, *c] または itertools.chain |
| 先頭への追加を何度も繰り返す | collections.deque の appendleft |
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「Pythonリストに追加|append・extend・insertの違い早見表」
検証した環境とコードの読み方
この記事のコードは、次の環境で実行して出力を確認しています。
| 項目 | 内容 |
|---|---|
| Python | 3.13.7 と 3.14.7(どちらも CPython) |
| OS | Linux(2 vCPU のコンテナ) |
| 外部ライブラリ | なし(標準ライブラリだけ) |
| 出力の違い | 速度以外の出力は 3.13 と 3.14 で同一でした |
コードブロックの直後にある「実行結果」は、スクリプトを python3.14 ファイル名.py で実行したときの出力そのままです。対話モード(REPL)で1行ずつ試しても同じ結果になります。
appendで末尾に1個追加する
append は「渡したものを、そのまま1個の要素として末尾に足す」メソッドです。 引数はちょうど1個です。
a = [1, 2, 3]
a.append(4)
print(a)
names = []
for n in ["sato", "suzuki", "tanaka"]:
names.append(n.upper())
print(names)
実行結果:
[1, 2, 3, 4]
['SATO', 'SUZUKI', 'TANAKA']
空のリストを用意して、ループの中で append を繰り返す形は、Python でもっともよく見る書き方です。数値、文字列、辞書、タプル、別のリストなど、どんな型でも1個の要素として入ります。
引数を2個渡すと、次のエラーになります。
a = [1]
a.append(1, 2)
実行結果:
TypeError: list.append() takes exactly one argument (2 given)
複数入れたいときは、次の extend を使います。
extendで複数の要素をまとめて追加する
extend は「渡したイテラブル(順番に取り出せるもの)の中身を、1個ずつ末尾に足す」メソッドです。 リスト、タプル、range、ジェネレータ式など、for で回せるものなら何でも渡せます。
a = [1, 2, 3]
a.extend([4, 5])
print(a)
a = [1]
a.extend(range(3))
print(a)
a = [1]
a.extend(x * x for x in range(3))
print(a)
a = [1]
a.extend({"x": 1, "y": 2})
print(a)
a = [1]
a.extend({"x": 1}.items())
print(a)
実行結果:
[1, 2, 3, 4, 5]
[1, 0, 1, 2]
[1, 0, 1, 4]
[1, 'x', 'y']
[1, ('x', 1)]
辞書を渡すとキーだけが入る点は覚えておくと便利です。キーと値の組がほしいときは .items() を渡します。
イテラブルではないもの(数値など)を渡すと、次のエラーになります。
a = [1]
a.extend(5)
実行結果:
TypeError: 'int' object is not iterable
数値を1個足したいだけなら a.append(5)、extend を使うなら a.extend([5]) と角かっこで包みます。
insertで位置を指定して追加する
insert は「第1引数のインデックスの前に、第2引数を1個入れる」メソッドです。 先頭に入れたいときは 0 を指定します。
a = [1, 2, 3]; a.insert(0, 0); print(a) # 先頭
a = [1, 2, 3]; a.insert(1, 99); print(a) # 2番目
a = [1, 2, 3]; a.insert(-1, 99); print(a) # 最後の要素の前
a = [1, 2, 3]; a.insert(100, 99); print(a) # 範囲より大きい
a = [1, 2, 3]; a.insert(-100, 99); print(a) # 範囲より小さい
実行結果:
[0, 1, 2, 3]
[1, 99, 2, 3]
[1, 2, 99, 3]
[1, 2, 3, 99]
[99, 1, 2, 3]
ここで押さえたい点が2つあります。
| 指定 | 結果 | 補足 |
|---|---|---|
insert(-1, x) |
最後の要素の「前」に入る | 末尾に入れたいなら append か insert(len(a), x) |
| 範囲外のインデックス | エラーにならず、先頭か末尾に入る | a[100] のような参照は IndexError ですが、insert は丸めて受け付けます |
insert(-1, x) は末尾ではなく「最後の1つ手前」に入るので、末尾への追加には append を使うのが確実です。
途中に複数まとめて入れるにはスライス代入
insert は1個ずつしか入れられません。複数を途中にまとめて入れたいときは、長さ0のスライスに代入します。
a = [1, 2, 3]
a[1:1] = [7, 8] # インデックス1の前に2個
print(a)
a = [1, 2, 3]
a[:0] = [-1, 0] # 先頭に2個
print(a)
a = [1, 2, 3]
a[len(a):] = [4, 5] # 末尾に2個(extend と同じ)
print(a)
実行結果:
[1, 7, 8, 2, 3]
[-1, 0, 1, 2, 3]
[1, 2, 3, 4, 5]
Python の公式チュートリアル(データ構造の章)でも、append は a[len(a):] = [x] と、extend は a[len(a):] = iterable と同じような動きだと説明されています。今回そのページを開いて確認しました。
+演算子とアンパックで新しいリストを作る
+ 演算子と [*a, *b] は、元のリストを書き換えずに、結合した新しいリストを作ります。 元のデータを残しておきたいときに向いています。
a = [1, 2, 3]
b = a + [4, 5]
print(a, b)
a = [1, 2]
b = [3, 4]
c = [*a, *b, 5]
print(a, c)
実行結果:
[1, 2, 3] [1, 2, 3, 4, 5]
[1, 2] [1, 2, 3, 4, 5]
アンパック(* を付けて中身を展開する書き方)は、途中に単独の値を混ぜたり、タプルや range を一緒に並べたりできるのが強みです。[0, *a, *range(3), *b] のように自由に組み立てられます。
一方、+ 演算子はリスト同士でしか使えません。
tags = ["python"]
tags = tags + "go"
実行結果:
TypeError: can only concatenate list (not "str") to list
a = [1]
a = a + (2, 3)
実行結果:
TypeError: can only concatenate list (not "tuple") to list
タプルを結合したいときは a + list(t) と変換するか、[*a, *t] と書くとそのまま通ります。
+=は元のリストを書き換える
見た目は a = a + b の省略形に見えますが、リストの += は extend と同じ動きで、元のリストそのものを書き換えます。 ここが + 演算子との大きな違いです。
a = [1, 2]; b = a
a += [3]
print(a, b, a is b)
a = [1, 2]; b = a
a = a + [3]
print(a, b, a is b)
実行結果:
[1, 2, 3] [1, 2, 3] True
[1, 2, 3] [1, 2] False
b = a は同じリストに別名を付けているだけなので、a += [3] のあとは b にも 3 が見えます。a = a + [3] は新しいリストを作って a に付け替えるので、b は元のままです。
関数に渡したリストでも、同じ違いが表れます。
def add_plus(lst):
lst = lst + [99] # 関数の中だけの新しいリスト
def add_iadd(lst):
lst += [99] # 呼び出し元のリストを書き換える
x = [1]; add_plus(x); print(x)
x = [1]; add_iadd(x); print(x)
実行結果:
[1]
[1, 99]
また、+= は extend と同じなので、右側にタプルや文字列も受け付けます。
a = [1]
a += (2, 3)
print(a)
tags = ["python"]
tags += "go"
print(tags)
実行結果:
[1, 2, 3]
['python', 'g', 'o']
tags + "go" は TypeError で止まりますが、tags += "go" は止まらずに1文字ずつ入ります。+ はリスト限定、+= はイテラブルなら何でも受け付ける、と覚えておくと混乱しません。
つまずきやすい3つのパターンと直し方
ここからは、検索でよく調べられている3つのパターンを、実際の出力で再現します。
1. 代入すると None になる
append・extend・insert はどれも、リストを書き換えるだけで値を返しません(戻り値は None です)。
a = [1, 2, 3]
print(a.append(4), a.extend([5]), a.insert(0, 0))
実行結果:
None None None
そのため、結果を同じ変数に代入すると、リストが None に置き換わります。
lst = [1, 2, 3]
lst = lst.append(4)
print(lst)
lst.append(5)
実行結果:
None
AttributeError: 'NoneType' object has no attribute 'append'
直し方は「代入をやめる」だけです。
| 書き方 | 結果 |
|---|---|
lst = lst.append(4) |
lst が None になる |
lst.append(4) |
lst が [1, 2, 3, 4] になる |
new = lst + [4] |
新しいリストがほしいときはこちら |
new = [*lst, 4] |
同じく新しいリストを作る |
print(lst.append(4)) や return lst.append(4) も同じ理由で None になります。追加してから print(lst)、return lst と2行に分けてください。公式チュートリアルにも「insert、remove、sort のようにリストを変更するだけのメソッドは None を返す。これは Python の変更可能なデータ構造すべてに共通する設計方針」という趣旨の説明があります。
2. append にリストを渡すと入れ子になる
append は渡したものを「1個の要素」として入れるので、リストを渡すとリストごと入ります。
a = [1, 2, 3]
a.append([4, 5])
print(a, len(a))
a = [1, 2, 3]
a.extend([4, 5])
print(a, len(a))
実行結果:
[1, 2, 3, [4, 5]] 4
[1, 2, 3, 4, 5] 5
長さが 4 と 5 で違う点に注目してください。中身をばらして足したいなら extend、行のまとまりとして足したいなら append です。たとえば表のデータを作るときは、rows.append([1, "pen", 120]) のように、あえて入れ子にする使い方が合っています。
すでに入れ子になったリストを平らにしたいときは、次のように書けます。
nested = [[1, 2], [3], [4, 5]]
print([x for sub in nested for x in sub])
import itertools
print(list(itertools.chain.from_iterable(nested)))
実行結果:
[1, 2, 3, 4, 5]
[1, 2, 3, 4, 5]
3. extend に文字列を渡すと1文字ずつ入る
文字列も「1文字ずつ取り出せるイテラブル」なので、extend に渡すと文字単位でばらばらに入ります。
tags = ["python"]
tags.extend("java")
print(tags)
実行結果:
['python', 'j', 'a', 'v', 'a']
エラーにならないため、気づきにくいパターンです。文字列を1個の要素として足すなら append、extend を使うなら角かっこで包みます。
tags = ["python"]; tags.append("java"); print(tags)
tags = ["python"]; tags.extend(["java"]); print(tags)
実行結果:
['python', 'java']
['python', 'java']
3つのパターンをまとめると、次のようになります。
| 症状 | 原因 | 直し方 |
|---|---|---|
| リストが None になる | 戻り値(None)を代入した | 代入せず lst.append(x) だけ書く |
[1, 2, 3, [4, 5]] と入れ子になる |
append にリストを渡した | extend か += を使う |
['j', 'a', 'v', 'a'] と1文字ずつ入る |
extend に文字列を渡した | append("java") か extend(["java"]) |
'int' object is not iterable |
extend に数値を渡した | append(5) か extend([5]) |
can only concatenate list |
+ の右側がリスト以外 | [x] で包むか [*a, *t] |
知っておくと役立つその他の注意点
3大パターン以外にも、追加まわりで調べられることが多い動きを4つ紹介します。
デフォルト引数に空のリストを書くと使い回される
def add_item(x, items=[]):
items.append(x)
return items
print(add_item(1))
print(add_item(2))
実行結果:
[1]
[1, 2]
デフォルト引数のリストは関数を定義したときに1回だけ作られ、呼び出しのたびに同じものが使われます。毎回新しいリストから始めたいときは、None を目印にします。
def add_item2(x, items=None):
if items is None:
items = []
items.append(x)
return items
print(add_item2(1))
print(add_item2(2))
実行結果:
[1]
[2]
掛け算で作った入れ子リストは中身が共有される
g = [[]] * 3
g[0].append(1)
print(g)
g = [[] for _ in range(3)]
g[0].append(1)
print(g)
実行結果:
[[1], [1], [1]]
[[1], [], []]
[[]] * 3 は同じ空リストを3回並べているだけなので、1つに append すると3つとも変わって見えます。内包表記で作れば、それぞれ別のリストになります。
ループ中に同じリストへ追加するときはコピーを回す
for で回しているリスト自身に append すると、追加した要素も回る対象になり、ループが終わらなくなります(この動きは一般に知られた仕様で、今回は止まらなくなるコードは実行していません)。a[:] でコピーを作って回すと安心です。
a = [1, 2, 3]
for x in a[:]: # a[:] はコピー
a.append(x * 10)
print(a)
実行結果:
[1, 2, 3, 10, 20, 30]
同じ辞書を何度も append すると全部同じ中身になる
append は値のコピーではなく、オブジェクトそのもの(参照)をリストに入れます。 ループの外で作った辞書を書き換えながら append すると、リストの全要素が同じ辞書を指すことになります。
rows = []
row = {"id": 0}
for i in range(3):
row["id"] = i
rows.append(row) # 毎回同じ辞書を入れている
print(rows)
実行結果:
[{'id': 2}, {'id': 2}, {'id': 2}]
ループの中で新しい辞書を作るか、copy() で複製してから追加すると、期待どおりに並びます。
rows = []
for i in range(3):
rows.append({"id": i}) # 毎回新しい辞書を作る
print(rows)
rows = []
row = {"id": 0}
for i in range(3):
row["id"] = i
rows.append(row.copy()) # 複製してから追加
print(rows)
実行結果:
[{'id': 0}, {'id': 1}, {'id': 2}]
[{'id': 0}, {'id': 1}, {'id': 2}]
タプルの中のリストに += すると、エラーが出るのに追加される
t = ([1],)
t[0] += [2]
print(t)
実行結果:
TypeError: 'tuple' object does not support item assignment
エラー後に print(t) を実行すると、次のように表示されます。
([1, 2],)
+= は「リストを書き換える」と「同じ場所に代入し直す」の2段階で動きます。書き換えは成功し、タプルへの代入の段階でエラーになるため、このような結果になります。t[0].extend([2]) か t[0].append(2) と書けば、エラーなしで追加できます。
速度比較(timeitの実測値)
大量に追加するときは、書き方によって速度が大きく変わります。 timeit で5回測って最も速い値を取りました。数値は検証環境(2 vCPU のコンテナ)でのもので、マシンによって変わります。大小関係の目安としてご覧ください。
測定に使ったコードの形は次のとおりです。
import timeit
def r(stmt, setup="pass", n=20):
t = min(timeit.repeat(stmt, setup, number=n, repeat=5)) / n * 1000
print(f"{t:8.3f} ms {stmt}")
r("a=[]\nfor x in src: a.append(x)", "src=range(100_000)")
r("a=[]; a.extend(src)", "src=range(100_000)")
10万件を追加する
| 書き方 | Python 3.13.7 | Python 3.14.7 |
|---|---|---|
for で a.append(x) を10万回 |
2.754 ms | 2.256 ms |
for で a += [x] を10万回 |
5.422 ms | 5.221 ms |
for で a.insert(len(a), x) を10万回 |
5.019 ms | 5.016 ms |
a.extend(src) を1回 |
1.487 ms | 1.230 ms |
[x for x in src](内包表記) |
1.914 ms | 2.177 ms |
list(src) |
1.483 ms | 1.282 ms |
まとめて入れられるなら extend が最も速く、1件ずつなら append が速いという結果です。a += [x] は毎回小さなリストを作るぶん、append の約2倍かかりました。
10万件のリスト同士を結合する
| 書き方 | Python 3.13.7 | Python 3.14.7 |
|---|---|---|
c = a + b |
0.660 ms | 0.668 ms |
c = [*a, *b] |
0.652 ms | 0.661 ms |
c = a.copy(); c.extend(b) |
0.745 ms | 0.753 ms |
c = a.copy(); c += b |
0.776 ms | 0.750 ms |
c = list(itertools.chain(a, b)) |
1.100 ms | 1.403 ms |
結合は、+ とアンパックがほぼ同じ速さでした。どちらを選んでも差は小さいので、読みやすさで決めて問題ありません。
先頭に1万回追加する
| 書き方 | Python 3.13.7 | Python 3.14.7 |
|---|---|---|
a.insert(0, x) を1万回 |
9.790 ms | 9.695 ms |
append を1万回してから a.reverse() |
0.189 ms | 0.206 ms |
deque の appendleft(x) を1万回 |
0.241 ms | 0.291 ms |
先頭への insert は、後ろの要素をすべて1つずつずらすため、件数が増えるほど時間がかかります。 今回の測定では append してから反転する方法の約50倍でした。先頭への追加が多い処理は、deque を使うか、末尾に足してから最後に反転すると軽くなります。
ループの中で a = a + [x] と書いた場合
| 書き方 | Python 3.13.7 | Python 3.14.7 |
|---|---|---|
a = a + [x] を1万回 |
106.461 ms | 106.125 ms |
a.append(x) を1万回 |
0.175 ms | 0.198 ms |
a = a + [x] は毎回リスト全体をコピーして作り直すので、1万回で約100ミリ秒、append の500倍以上かかりました。ループの中で少しずつ足すときは append か += を使うと覚えておくと、件数が増えても安心です。
どれを使うかの判断表
| 状況 | おすすめ | 理由 |
|---|---|---|
| ループの中で1件ずつ足す | append |
速く、意図が読み取りやすい |
| 別のリストの中身を全部足す | extend |
1回の呼び出しで済み、最も速い |
| 変換しながら新しいリストを作る | 内包表記 | 空リスト+append より短く書ける |
| 元のリストを残したい | a + b / [*a, *b] |
新しいリストができる |
| 関数の引数を書き換えたくない | a + b / [*a, *b] |
呼び出し元に影響しない |
| タプルや range も混ぜて結合する | [*a, *t, *r] |
型をそろえる手間がない |
| 先頭や途中に1個入れる | insert |
位置を指定できる |
| 先頭への追加が何度もある | deque.appendleft |
件数が増えても速い |
| 並び順を保ったまま入れる | bisect.insort |
ソート済みの位置を自動で探す |
図にすると、次のような流れで選べます。
flowchart TD
A[リストに追加したい] --> B{元のリストを残す?}
B -- 残す --> C["a + b または [*a, *b]"]
B -- 書き換えてよい --> D{追加する個数}
D -- 1個 --> E{位置}
E -- 末尾 --> F[append]
E -- 先頭や途中 --> G[insert]
D -- 複数 --> H{位置}
H -- 末尾 --> I["extend または +="]
H -- 先頭や途中 --> J["スライス代入 a[i:i] = items"]
コピペで使える追加レシピ集
よくある場面ごとに、そのまま使えるコードをまとめます。
重複しないときだけ追加する
a = [1, 2, 3]
for x in [2, 3, 4]:
if x not in a:
a.append(x)
print(a)
# 2つのリストを順番を保って重複なしで結合
print(list(dict.fromkeys([1, 2, 3] + [2, 3, 4])))
実行結果:
[1, 2, 3, 4]
[1, 2, 3, 4]
x not in a はリストを先頭から探すため、件数が多いときは dict.fromkeys や集合(set)を使うと速くなります。
3つ以上のリストを1つにまとめる
import itertools
print(list(itertools.chain([1, 2], [3], [4, 5])))
print([*[1, 2], *[3], *[4, 5]])
print(sum([[1, 2], [3], [4, 5]], []))
実行結果:
[1, 2, 3, 4, 5]
[1, 2, 3, 4, 5]
[1, 2, 3, 4, 5]
sum(リストのリスト, []) は短く書けますが、内部で a = a + b を繰り返すため、件数が多いときは itertools.chain のほうが向いています。
元のリストを残して1個だけ足したリストを作る
a = [1, 2, 3]
b = [*a, 4]
print(a, b)
a = [1, 2, 3]
b = a.copy()
b.append(4)
print(a, b)
実行結果:
[1, 2, 3] [1, 2, 3, 4]
[1, 2, 3] [1, 2, 3, 4]
先頭と末尾の両方に追加する(deque)
from collections import deque
d = deque([1, 2, 3])
d.appendleft(0)
d.append(4)
print(d)
print(list(d))
実行結果:
deque([0, 1, 2, 3, 4])
[0, 1, 2, 3, 4]
ソート済みのリストに順番を保って追加する
import bisect
s = [10, 20, 30]
bisect.insort(s, 25)
print(s)
実行結果:
[10, 20, 25, 30]
2次元リスト(表形式)に行や列を追加する
行を足すときは append、各行に列を足すときは行ごとに append、1行だけ複数列を足すときは extend を使います。
table = [[1, 2], [3, 4]]
table.append([5, 6]) # 行を追加
print(table)
for r in table: # すべての行に列を追加
r.append(0)
print(table)
table[0].extend([9, 9]) # 1行目だけ2列追加
print(table)
実行結果:
[[1, 2], [3, 4], [5, 6]]
[[1, 2, 0], [3, 4, 0], [5, 6, 0]]
[[1, 2, 0, 9, 9], [3, 4, 0], [5, 6, 0]]
空リストと append の組み合わせを内包表記に書き換える
「空のリストを作って、条件に合うものだけ変換して append する」処理は、内包表記で1行にまとめられます。結果は同じです。
src = ["3", "x", "5"]
out = []
for s in src:
if s.isdigit():
out.append(int(s))
print(out)
print([int(s) for s in src if s.isdigit()])
実行結果:
[3, 5]
[3, 5]
処理が1〜2行で済むなら内包表記、途中で複数の処理やログ出力をはさむなら for と append、という使い分けが読みやすさの面でおすすめです。
同じ値で埋める・タプルを要素として足す
a = [1, 2, 3]
a.extend([0] * 3) # 0 を3個まとめて追加
print(a)
a = [1, 2, 3]
a.append(a[-1] + 1) # 最後の値に1足した数を追加
print(a)
a = []
a.append((1, "pen")) # タプルは丸かっこを二重にして渡す
a.append((2, "note"))
print(a)
実行結果:
[1, 2, 3, 0, 0, 0]
[1, 2, 3, 4]
[(1, 'pen'), (2, 'note')]
a.append(1, "pen") と書くと引数が2個になり TypeError になるので、タプルを足すときは a.append((1, "pen")) のように丸かっこを二重にします。
リスト以外に追加するときの対応表
リストと同じ感覚で append を呼ぶと、型によっては AttributeError になります。型ごとの書き方を並べます。
t = (1, 2)
t += (3,) # タプルは新しいタプルを作る
print(t)
s = {1, 2}
s.add(3) # 集合は add(1個)と update(複数)
s.update([4, 5])
print(s)
d = {"a": 1}
d["b"] = 2 # 辞書はキーを指定して代入
d.update({"c": 3})
print(d)
実行結果:
(1, 2, 3)
{1, 2, 3, 4, 5}
{'a': 1, 'b': 2, 'c': 3}
| 型 | 1個追加 | 複数追加 | append を呼んだとき |
|---|---|---|---|
| リスト | append(x) |
extend(items) |
追加される |
| タプル | t += (x,) |
t += (x, y) |
AttributeError: 'tuple' object has no attribute 'append' |
| 集合 | add(x) |
update(items) |
AttributeError: 'set' object has no attribute 'append' |
| 辞書 | d[key] = value |
update({...}) |
AttributeError: 'dict' object has no attribute 'append' |
| 文字列 | s += "x" |
"".join([...]) |
AttributeError: 'str' object has no attribute 'append' |
| deque | append / appendleft |
extend / extendleft |
追加される |
よくある質問
Q. append と extend はどちらが速いですか? A. 複数の要素をまとめて足すなら extend のほうが速いです。今回の測定では、10万件を for で append した場合が約2.3〜2.8ミリ秒、extend 1回が約1.2〜1.5ミリ秒でした。1件ずつしか手に入らない場合は append を使い、すでにリストなどにまとまっている場合は extend を選ぶとよいでしょう。
Q. リストの先頭に追加するにはどうすればよいですか?
A. a.insert(0, x) で先頭に入ります。複数なら a[:0] = [x, y] です。先頭への追加を何千回も繰り返すときは、collections.deque の appendleft を使うか、append で末尾に足してから最後に reverse() すると速くなります。
Q. a += [x] と a.append(x) は同じ結果になりますか?
A. リストに1個足すという結果は同じです。ただし += は右側のイテラブルを展開するので、a += "ab" は2文字に分かれて入ります。1個の値を足す意図をはっきり伝えるには append が向いています。
Q. append した結果を1行で受け取りたいときはどう書きますか?
A. append の戻り値は None なので、新しいリストを作る書き方に切り替えます。new = lst + [x] か new = [*lst, x] と書けば、元のリストを残したまま、1個足したリストを1行で受け取れます。
まとめ
- 末尾に1個は append、複数は extend、位置指定は insert が基本です。
- append・extend・insert の戻り値は None です。
lst = lst.append(x)と代入せず、lst.append(x)だけ書きます。 - append にリストを渡すと入れ子になり、extend に文字列を渡すと1文字ずつ入ります。 中身をばらすなら extend、1個として足すなら append です。
- + とアンパックは新しいリストを作り、+= は元のリストを書き換えます。 別名や関数の引数がある場面では、この違いが結果に表れます。
- 速度は extend が最も速く、次が append でした。ループ内の
a = a + [x]は append の500倍以上かかりました。 - 先頭への追加が多いときは deque か、末尾に足してから反転する方法が軽く動きます。
- 迷ったら、冒頭の早見表で「追加単位・元のリスト・戻り値」の3列を確認してください。
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「Pythonリストに追加|append・extend・insertの違い早見表」
株式会社RJCでは、Pythonのリスト操作のような基礎の仕組みを仲間と学び合っています。こうした知識を共有しながら、日々技術を磨いています。
株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。
WE ARE HIRING
RJCで一緒に開発しながら、
成長を楽しみませんか?
RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!
- 127日年間休日
- 12時間平均残業時間
- 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!
ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。