Pythonのリスト(配列)を任意の値・要素数で初期化

Modified: | Tags: Python, リスト

Pythonのリスト(配列)を任意の値・要素数で初期化する方法を説明する。

NumPy配列numpy.ndarrayの初期化については以下の記事を参照。

空リストを作成

空のリスト(要素数ゼロのリスト)は以下のように作成する。リストの要素数(長さ)は組み込み関数len()で取得できる。

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のリストは動的に要素を追加したり削除したりできるので初期化が必要な場面は少ないが、すべての要素が任意の値で埋められた任意の要素数のリストを作成したい場合は、以下のように*演算子を使う。

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()を使う。

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

リスト内包表記を使って以下のように書けばよい。

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])

関連カテゴリー

関連記事