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期連続の黒字決算。

ABOUT RJC RJCがどんな会社か知る 考え方、研修、働き方、福利厚生、社員の前職まで。RJCのことが丸わかり! RJC丸わかりページへ JOB DESCRIPTION 仕事内容・待遇を見てみる 仕事内容、給与・待遇、選考の流れ。経験者も未経験も!応募前に知りたいこと、まとめました! 募集要項を見る ENTRY エントリーする エントリーは1〜2分・履歴書不要です。まずは話を聞いてみたい、という方でも歓迎です! エントリーフォームへ

RJCで一緒に開発しながら、 成長を楽しみませんか?