本記事ではPythonのappendメソッドの使い方について、extendメソッドとの比較を行いながら解説します。

appendメソッド・extendメソッドの違いは、分かってしまえばなんてことないものです。

ここでしっかり整理しておきましょう。

  1. $ python3 –version
  2. Python 3.8.2


Pythonのリスト操作

appendメソッドとextendメソッドはリスト操作のメソッドです。

他にどのようなメソッドがあり、どのような位置にあるメソッドかを確認してみましょう。

Pythonのリストに要素を追加するメソッドは以下です。

  • append(末尾に要素を追加する
  • extend(末尾にリスト・タプルを連結する
  • insert(指定位置に要素を追加する)

appendメソッドとextendメソッドの違いは本記事で解説します。

またリストから要素を削除するメソッドは以下です。

  • pop(引数なしで末尾の要素を削除する)
  • remove(指定位置の要素を削除する)
  • clear(全要素を削除する)

popメソッドにインデックスを指定すると、removeと同様に使用することができます。


appendメソッドとextendメソッドの中身

appendメソッドは以下の式と等価です。

  • aplist[len(aplist):] = [x]

Pythonのスライス操作をするときは、上記の記述方法のような「:(コロン)」演算子をよく使います。

またextendメソッドは以下の式と等価です。

  • exlist[len(exlist):] = iterable

iterableについては次項で説明します。

appendメソッドとextendメソッドの中で何をしているかきちんと理解するためには、スライス操作の理解が必要不可欠でしょう。


Pythonのスライス操作

今後の解説に必要な最低限のPythonの知識、それがスライス操作とiterableについてです。

全てを説明すると記事が1本書けてしまうので、本記事では開始のみに絞って解説しましょう。


スライス操作の仕組み

スライス操作の文法は以下です。開始・終了・間隔を指定することで文字列・リスト・タプルを切り取ります。

  • list[start:stop:step]

スライス操作は実際に見てみるのが早いでしょう。次項から実際の挙動を確認します。


スライス操作で開始を指定する

startで開始位置を指定です。

  1. >>> numlist = [1, 2, 3, 4, 5]
  2. >>> numlist[1:]
  3. [2, 3, 4, 5]
  4. >>> numlist[2:]
  5. [3, 4, 5]

前項のlen(aplist)は配列の長さの取得ですから、numlistでは以下のようになります。

  1. >>> len(numlist)
  2. 5
  3. >>> numlist[5:]
  4. []

0始まりなので5開始の要素は空の状態です。


Pythonにおけるiterable

Pythonのiterableとはどのようなものでしょうか。

iterableには「反復可能な・繰り返し可能な」という意味があります。簡単に説明するとiterableはfor文で処理できるデータ構造です。


文字列におけるiterable

文字列もfor文でループさせることができるようになっています。

  1. >>> for str in ‘flo’:
  2. … print(str)
  3. f
  4. l
  5. o

上記のように1文字ずつバラバラの状態で表示されている筈です。


リスト・タプルにおけるiterable

リスト・タプルももちろん反復可能なデータになります。

  1. >>> for arr in [‘financier’, ‘florentin’]:
  2. … print(arr)
  3. financier
  4. florentin
  5. >>> for tpl in (‘financier’, 9):
  6. … print(tpl)
  7. financier
  8. 9


appendメソッドの使い方

appendメソッドはリストの末尾に要素を追加するメソッドです。


文字列を追加する

まずは文字列を追加してみましょう。

  1. >>> aplist = [‘affogato’, ‘biscuit’, ‘crepe’, ‘doughnut’]
  2. >>> aplist.append(‘florentin’)
  3. >>> aplist
  4. [‘affogato’, ‘biscuit’, ‘crepe’, ‘doughnut’, ‘florentin’]

aplist配列の末尾に文字列のflorentinが追加されました。


配列を追加する

次に配列を追加してみましょう。

  1. >>> aplist = [‘affogato’, ‘biscuit’, ‘crepe’, ‘doughnut’]
  2. >>> flist = [‘financier’, ‘florentin’]
  3. >>> aplist.append(flist)
  4. >>> aplist
  5. [‘affogato’, ‘biscuit’, ‘crepe’, ‘doughnut’, [‘financier’, ‘florentin’]]

今度は配列のままのflistが末尾に追加されました。


タプルを追加する

最後にタプルを追加してみましょう。

  1. >>> aplist = [‘affogato’, ‘biscuit’, ‘crepe’, ‘doughnut’]
  2. >>> ftuple = (‘financier’, 9)
  3. >>> aplist.append(ftuple)
  4. >>> aplist
  5. [‘affogato’, ‘biscuit’, ‘crepe’, ‘doughnut’, (‘financier’, 9)]

タプルのままのftupleが末尾に追加されました。


appendメソッドの仕組み

何故このような動きになるのでしょうか。


文字列におけるappendメソッドの動き

appendメソッドは以下の式と等価でした。

  • aplist[len(aplist):] = [x]

len(aplist)は4なので上記の式は以下のようになります。

  1. >>> aplist[4:] = [‘florentin’]
  2. >>> aplist
  3. [‘affogato’, ‘biscuit’, ‘crepe’, ‘doughnut’, ‘florentin’]

つまり存在しないインデックス4の位置に、文字列を含む配列を指定しているということです。


リスト・タプルにおけるappendメソッドの動き

もうお分かりかと思いますが、リストとタプルの具体例と実行結果を以下に記載します。

  1. >>> aplist[len(aplist):] = [[‘financier’, ‘florentin’]]
  2. >>> aplist
  3. [‘affogato’, ‘biscuit’, ‘crepe’, ‘doughnut’, [‘financier’, ‘florentin’]]
  4. >>> aplist[len(aplist):] = [(‘financier’, 9)]
  5. >>> aplist
  6. [‘affogato’, ‘biscuit’, ‘crepe’, ‘doughnut’, [‘financier’, ‘florentin’], (‘financier’, 9)]

さてリストはイテラブルなデータ構造でした。

リストの中に要素があるのでそのまま格納されます。より分かりやすいように複数要素で書いてみましょう。

  1. >>> aplist[len(aplist):] = [[‘a’, ‘b’], [‘c’, ‘d’], [‘e’, ‘f’]]
  2. >>> aplist
  3. [‘affogato’, ‘biscuit’, ‘crepe’, ‘doughnut’, [‘a’, ‘b’], [‘c’, ‘d’], [‘e’, ‘f’]]

[x]のxにあたる部分が末尾に追加されたのがお分かり頂けたでしょうか。

appendの動きを正しく掴むことができたと思ったら、次の項の学習に移って下さい。


extendメソッドの使い方

extendメソッドはリストの末尾にリスト・タプルを結合するメソッドです。


文字列を追加する

まずは文字列を追加してみましょう。

  1. >>> exlist = [‘giraffe’, ‘horse’, ‘fox’, ‘jaguar’]
  2. >>> exlist.extend(‘koala’)
  3. >>> exlist
  4. [‘giraffe’, ‘horse’, ‘fox’, ‘jaguar’, ‘k’, ‘o’, ‘a’, ‘l’, ‘a’]

‘koala’が1文字ずつに分解されてしまいました。末尾には追加されましたがこれは想定していた挙動と違う方が多いのではないでしょうか。


リストを追加する

次にリストを追加してみましょう。

  1. >>> exlist = [‘giraffe’, ‘horse’, ‘fox’, ‘jaguar’]
  2. >>> klist = [‘koala’, ‘kangaroo’]
  3. >>> exlist.extend(klist)
  4. >>> exlist
  5. [‘giraffe’, ‘horse’, ‘fox’, ‘jaguar’, ‘koala’, ‘kangaroo’]

exlist配列の末尾に文字列のkoalaとkangarooが追加されました。


タプルを追加する

最後にタプルを追加してみましょう。

  1. >>> exlist = [‘giraffe’, ‘horse’, ‘fox’, ‘jaguar’]
  2. >>> ktuple = (‘koala’, 5)
  3. >>> exlist.extend(ktuple)
  4. >>> exlist
  5. [‘giraffe’, ‘horse’, ‘fox’, ‘jaguar’, ‘koala’, 5]

exlist配列の末尾に文字列のkoalaと数字の5が各々追加されました。


extendメソッドの仕組み

文字列追加の動きは予想と随分違ったのではないでしょうか。

どうしてこのような動きになったのか、しっかり整理・理解しておきましょう。


文字列におけるextendメソッドの動き

extendメソッドは以下の式と等価でした。

  • exlist[len(exlist):] = iterable

len(exlist)は4なので上記の式は以下のようになります。

  1. >>> exlist[4:] = ‘koala’
  2. >>> exlist
  3. [‘giraffe’, ‘horse’, ‘fox’, ‘jaguar’, ‘k’, ‘o’, ‘a’, ‘l’, ‘a’]

つまり存在しないインデックス4の位置に、イテラブルなデータ構造である文字列を指定しているということです。

文字列をiterableとして扱いfor文で表示したとき、1文字ずつに分解した状態でprintされていたのを覚えていますか。

あのループと同じことがここでも起きています。対象の配列に格納されるとき、文字列は1文字ずつ配列に格納される仕組みです。


リスト・タプルにおけるextendメソッドの動き

リストとタプルの具体例を以下に記載します。

  1. >>> exlist[len(exlist):] = [‘koala’, ‘kangaroo’]
  2. >>> exlist
  3. [‘giraffe’, ‘horse’, ‘fox’, ‘jaguar’, ‘koala’, ‘kangaroo’]
  4. >>> exlist[len(exlist):] = (‘koala’, 5)
  5. >>> exlist
  6. [‘giraffe’, ‘horse’, ‘fox’, ‘jaguar’, ‘koala’, ‘kangaroo’, ‘koala’, 5]

これまで説明してきた概念をきちんと理解していれば、何故このような結果になるかが分かる筈です。


appendメソッドとextendメソッドの違い

くどいようですがもう一度書いておきます。

  • aplist[len(aplist):] = [x]
  • exlist[len(exlist):] = iterable

配列の中身を数字に置き換えてみましょう。

appendメソッドに指定するxはiterableでなくても構いません。何故なら内部的には下のような処理をしているのと変わらないからです。

  1. >>> aplist = list(range(3))
  2. >>> aplist.append(4)
  3. >>> aplist
  4. [1, 2, 3, 4]
  5. >>> aplist = [1, 2, 3]
  6. >>> aplist[len(aplist):] = [4]
  7. >>> aplist
  8. [1, 2, 3, 4]

extendメソッドで同じことをしてみましょう。

  1. >>> exlist = list(range(3))
  2. >>> exlist.extend(4)
  3. Traceback (most recent call last):
  4. File “<stdin>”, line 1, in <module>
  5. TypeError: ‘int’ object is not iterable

「intオブジェクトはイテラブルではありません」と起こられてしまいました。

  1. >>> exlist = [1, 2, 3]
  2. >>> exlist[len(exlist):] = 4
  3. Traceback (most recent call last):
  4. File “<stdin>”, line 1, in <module>
  5. TypeError: can only assign an iterable

このようにextendメソッドにはiterableしか指定できない構造になっています。

メソッドに隠れてしまって見えませんが、開発者はこのような仕組み上の違いがあることを認識しておくべきです。


おわりに

Pythonにはappendやextendのように楽に書けるメソッドが沢山用意されています。

しかし内部の仕組みを理解しないで使用していれば、似たようなメソッドの使い分けが分からず困ってしまうでしょう。

丁度extendメソッドをappendメソッドと同じ方法で使用してエラーになるようにです。

言語をただ使えるようになるのではなく、仕組みを理解して正しく使用できるようになって初めて習得したといえるのではないでしょうか。