Pythonのリスト(配列)を任意の値・要素数で初期化
Pythonのリスト(配列)を任意の値・要素数で初期化する方法を説明する。
NumPy配列numpy.ndarray
の初期化については以下の記事を参照。
空リストを作成
空のリスト(要素数ゼロのリスト)は以下のように作成する。リストの要素数(長さ)は組み込み関数len()
で取得できる。
- 関連記事: Pythonでリストのサイズ(要素数)を取得
l_empty = []
print(l_empty)
# []
print(len(l_empty))
# 0
append()
で要素を追加したり、remove()
で削除したりできる。
l_empty.append(100)
l_empty.append(200)
print(l_empty)
# [100, 200]
l_empty.remove(100)
print(l_empty)
# [200]
要素の追加・削除については以下の記事を参照。
- 関連記事: Pythonでリスト(配列)に要素を追加するappend, extend, insert
- 関連記事: Pythonでリスト(配列)の要素を削除するclear, pop, remove, del
任意の値・要素数でリストを初期化
上述のようにPythonのリストは動的に要素を追加したり削除したりできるので初期化が必要な場面は少ないが、すべての要素が任意の値で埋められた任意の要素数のリストを作成したい場合は、以下のように*
演算子を使う。
l = [0] * 10
print(l)
# [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
print(len(l))
# 10
要素数によらず、もとのリストの要素が繰り返されたリストが生成される。
print([0, 1, 2] * 3)
# [0, 1, 2, 0, 1, 2, 0, 1, 2]
連番のリストを生成したい場合はrange()
を使う。
- 関連記事: Pythonのrange関数の使い方
2次元配列(リストのリスト)を初期化する際の注意
リストのリストによって多次元配列の形のデータが作成できるが、この場合の初期化は注意が必要。
以下のように書くと一見よさそうだがNG。
l_2d_ng = [[0] * 4] * 3
print(l_2d_ng)
# [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
一つのリストを更新するとすべてのリストが変更されてしまう。
l_2d_ng[0][0] = 5
print(l_2d_ng)
# [[5, 0, 0, 0], [5, 0, 0, 0], [5, 0, 0, 0]]
l_2d_ng[0].append(100)
print(l_2d_ng)
# [[5, 0, 0, 0, 100], [5, 0, 0, 0, 100], [5, 0, 0, 0, 100]]
これは、要素のリストがすべて同じオブジェクトであるため。
print(id(l_2d_ng[0]) == id(l_2d_ng[1]) == id(l_2d_ng[2]))
# True
リスト内包表記を使って以下のように書けばよい。
- 関連記事: Pythonリスト内包表記の使い方
l_2d_ok = [[0] * 4 for i in range(3)]
print(l_2d_ok)
# [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
要素のリストはそれぞれ異なるオブジェクトとして扱われる。
l_2d_ok[0][0] = 100
print(l_2d_ok)
# [[100, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
print(id(l_2d_ok[0]) == id(l_2d_ok[1]) == id(l_2d_ok[2]))
# False
リスト内包表記のin
のあとは要素数が所望の行数と等しいリスト(イテラブル)であれば何でもいいため、以下のようにも書ける。例では[1]
だがどんな値でも構わない。
l_2d_ok_2 = [[0] * 4 for i in [1] * 3]
print(l_2d_ok_2)
# [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
l_2d_ok_2[0][0] = 100
print(l_2d_ok_2)
# [[100, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
print(id(l_2d_ok_2[0]) == id(l_2d_ok_2[1]) == id(l_2d_ok_2[2]))
# False
多次元配列を生成したい場合はリスト内包表記を入れ子にしていけばよい。
l_3d = [[[0] * 2 for i in range(3)] for j in range(4)]
print(l_3d)
# [[[0, 0], [0, 0], [0, 0]], [[0, 0], [0, 0], [0, 0]], [[0, 0], [0, 0], [0, 0]], [[0, 0], [0, 0], [0, 0]]]
l_3d[0][0][0] = 100
print(l_3d)
# [[[100, 0], [0, 0], [0, 0]], [[0, 0], [0, 0], [0, 0]], [[0, 0], [0, 0], [0, 0]], [[0, 0], [0, 0], [0, 0]]]
なお、多次元配列で込み入った処理をするのであれば、NumPyを使ったほうが楽な場合が多い。NumPy配列numpy.ndarray
の初期化については以下の記事を参照。
タプル、配列(array型)の場合
タプルの場合も同様だが、要素数1のタプルは,
が必要なので注意。
t = (0,) * 5
print(t)
# (0, 0, 0, 0, 0)
ここまで説明してきたリスト(list
型)は厳密には配列とは異なり、Pythonには標準ライブラリに配列を扱うarrayモジュールが用意されている。
array
型の場合はコンストラクタに初期化したリストを渡せばよい。
import array
a = array.array('i', [0] * 5)
print(a)
# array('i', [0, 0, 0, 0, 0])