検索
連載

[解決!Python]リスト(配列)を初期化するには([]、list関数、リスト内包表記)解決!Python

Pythonでは配列は「リスト」というデータ構造として実装されている。list関数やリスト内包表記などを使って、これを初期化する方法をまとめて紹介する。

PC用表示 関連情報
Share
Tweet
LINE
Hatena
「解決!Python」のインデックス

連載目次

* 本稿は2020年12月4日に公開された記事をPython 3.12.0で動作確認したものです(確認日:2023年11月1日)。


# リスト(配列)の初期化:角かっこ「[]」で囲み、要素をカンマ「,」区切りで並べる
empty_list = []  # 空のリスト
print(empty_list)  # []

int_list = [0, 1, 2# 整数リスト(整数配列)
print(int_list)  # [0, 1, 2]

mylist = [0, 'abc', 1, 'def'# リスト(配列)には任意の型の要素を格納できる
print(mylist)  # [0, 'abc', 1, 'def']

# リスト(配列)の初期化:list関数を呼び出す
int_list = list()  # 空のリスト(配列)
print(int_list)  # []

int_list = list((4, 5, 6))  # タプルの要素を基にリスト(配列)が作成される
print(int_list)  # [4, 5, 6]

int_list = list(range(5))  # rangeオブジェクトから整数リスト(整数配列)を作成
print(int_list)  # [0, 1, 2, 3, 4]

str_list = list('python'# 文字列の各文字を要素とするリストを作成
print(str_list)  # ['p', 'y', 't', 'h', 'o', 'n']

# リスト内包表記
int_list = [x for x in range(0, 10, 2)]  # rangeオブジェクトからリストを作成
print(int_list)  # [0, 2, 4, 6, 8]

int_list = [x for x in range(10) if x % 2 == 1# if節を用いる例
print(int_list)  # [1, 3, 5, 7, 9]

# if else式を使うときにはfor節に続けずに、内包表記の先頭に記述する
str_list = [c.upper() if c.islower() else c.lower() for c in 'AbCdE']
print(str_list)  # ['a', 'B', 'c', 'D', 'e']

# リストのリスト(配列の配列)
mylist = [[0, 1, 2], [3, 4, 5]]  # 2次元のリスト(配列)の作成
print(mylist)  # [[0, 1, 2], [3, 4, 5]]

mul_tbl = [[x * y for x in range(1, 4)] for y in range(1, 5)]
print(mul_tbl)  # [[1, 2, 3], [2, 4, 6], [3, 6, 9], [4, 8, 12]]


リスト(配列)の初期化

 多くのプログラミング言語における「配列」は、Pythonではリストとして実装されている。ここでは、リスト(配列)を初期化する方法をまとめる。

 リスト(配列)を初期化するには、幾つかの方法がある。

  • 角かっこ「[]」内に、その要素をカンマ「,」で区切って並べていく
  • list関数にその要素となるものを格納している反復可能オブジェクトを与える
  • リスト内包表記を使用する

 下の2つは後で見るとして、まず角かっこを使用する方法を見ていこう。要素を持たない空のリスト(空の配列)を作成するには、角かっこに何も含めないか、後で見るlist関数に引数を指定しないで呼び出せばよい。

# 空のリスト(配列)の作成
empty_list = []
print(empty_list)  # []

empty_list = list()
print(empty_list)  # []


 リストに要素を含めるには、それらをカンマで区切って並べていく。

int_list = [1, 2, 3]
print(int_list)  # [1, 2, 3]

str_list = ['foo', 'bar', 'baz']
print(str_list)  # ['foo', 'bar', 'baz']


 その要素は、インデックスを用いてアクセスしたり、for文で列挙したりすることで使用できる。

print(int_list[0])  # 先頭要素にアクセス:1

print(str_list[-1])  # 末尾要素にアクセス:baz

for item in str_list:
    print(item)  # foo、bar、bazが順番に表示される


 リストには異なる型の要素を混在させて、格納できる。他の言語では、例えばint型の配列には整数しか格納できない、ということがよくあるが、Pythonのリストではそういうことはない。

mylist = [1, 'foo', 2, 'bar'# 整数と文字列を要素とするリスト


 とはいえ、リストは繰り返し処理でその要素を扱ったり、要素を一括して処理したりすることを念頭に置いたデータ構造なので、例えば整数のみを含むリスト、あるいは複数の項目で構成されるタプルを要素とするリスト、さらに構造化を進めて、何らかのクラスのインスタンスを要素とするリストのように、同種の項目の集まりを格納するために使用するのが好ましい。

list関数

 リスト(配列)は、list関数を使っても作成できる。このときには、既に見たように引数を指定しなければ空のリストが作成される。そうでないときには、リストの要素となるものを格納している反復可能オブジェクトを引数に指定する。以下に例を示す。

empty_list = list()  # 空のリスト(配列)の作成

int_tuple = (0, 1, 2)
int_list = list(int_tuple)  # 反復可能オブジェクト(タプル)からリストを作成
print(int_list)  # [0, 1, 2]


 連続する整数配列を作成するときには、range関数とlist関数を組み合わせるのが一般的といえる。

int_list = list(range(5))
print(int_list)  # [0, 1, 2, 3, 4]


 ただし、range関数が返すrangeオブジェクトは、リスト(配列)よりもメモリ消費の点で効率的である。整数列をリストとして持っている必要がなければ、多くの場所ではrangeオブジェクトを使った方がよいかもしれない。

 なお、文字列もまた反復可能オブジェクトである。よって、文字列を構成する各文字を要素とするリストは次のようにすることで簡単に作成できる。

my_str = 'python'
str_list = list(my_str)
print(str_list)  # ['p', 'y', 't', 'h', 'o', 'n']


リスト内包表記

 Pythonではリスト内包表記という方法でもリスト(配列)を初期化できる。その基本構文は次のようになっている。

[変数を使って要素の値を計算する式 for 変数 in 反復可能オブジェクト]


 実際にはこれは、以下のfor文と同じ意味となる。

結果を保存するリスト = []
for 変数 in 反復可能オブジェクト:
    結果を保存するリスト.append(変数を使って要素の値を計算する式)


 以下に例を示す。

int_list = [x * 2 for x in range(5)]
print(int_list)  # [0, 2, 4, 6, 8]


 上のfor文での置き換えに従うと、これは次のコードと同等ということだ。

int_list = []
for x in range(5):
    int_list.append(x * 2)

print(int_list)  # [0, 2, 4, 6, 8]


 リスト内包表記のfor節には続けてif節を記述できる。これは反復可能オブジェクトから取り出した値が特定の条件に合致するときにだけ、「変数を使って要素の値を計算する式」の評価を行うために使用する。以下に例を示す。

int_list = [x for x in range(10) if x % 2]
print(int_list)  # [1, 3, 5, 7, 9]


 上記コード例のif節では「if x % 2」と条件を指定している。これは反復可能オブジェクトであるrange(10)オブジェクトから変数xに取り出した値が奇数のときにだけ、「変数を使って要素の値を計算する式」である「x」を評価することを意味する(奇数であれば「if x % 2」の値は1となり、Pythonでは1は真と見なされるので、ここでは「== 1」という記述は省略している)。「x」という式は取り出した値そのものなので、ここでは「[1, 3, 5, 7, 9]」という結果が得られる。

 その一方で、変数xに取り出した値が条件に合致しないときにも、何らかの値を算出したいという場合がある。そうしたときには、for節に続けてif節を記述するのではなく、要素の値を計算する式の中で三項演算子(if式)を記述する。

str_list = [c.upper() if c.islower() else c.lower() for c in 'AbCdE']
print(str_list)  # ['a', 'B', 'c', 'D', 'e']


 ここでは、反復可能オブジェクトとして文字列'AbCdE'を用いている。新しく作成するリストの要素の値を計算する式は「c.upper() if c.islower() else c.lower()」だ。これは、文字列の個々の文字が小文字かどうかを調べて、小文字であればそれをupperメソッドで大文字化して、そうでなければlowerメソッドで小文字化する。よって、元の文字列とは大文字小文字が反転したものを要素とするリストが得られるということだ。

リストのリスト(配列の配列)

 最後にリストのリスト(配列の配列)、つまりリストを要素とするリストの初期化についても簡単に見ておく。といっても、難しいことはなく、角かっこの中にさらに角かっこを使って記述していくだけだ。あるいは、角かっこの中に既存のリストを置いてもよい。

int_list_list = [[0, 1, 2], [3, 4, 5]]
print(int_list_list)  # [[0, 1, 2], [3, 4, 5]]

l1 = [0, 1, 2]
l2 = [3, 4, 5]
int_list_list = [l1, l2]
print(int_list_list)  # [[0, 1, 2], [3, 4, 5]]


 ただし、後者のように既存のリストを、新しいリストの要素とするときには注意が必要だ。以下のコードを見てほしい。

l1 = [0, 1, 2]
l2 = [3, 4, 5]
int_list_list = [l1, l2]

l1[0] = -1
print(int_list_list)  # [[-1, 1, 2], [3, 4, 5]]

int_list_list[1][0] = 100
print(l2)  # [100, 4, 5]


 ここでは変数l1とl2に保存されているリストを要素として、リストのリストを作成しているが、l1の要素を書き換えた結果がint_list_listに影響し、逆にint_list_listの要素を書き換えた結果がl2に影響している。これは、リストの要素は他のオブジェクトへの参照となっているからだ。この点には注意が必要だ。

 リスト内包表記でリストのリストを作成するには、リスト内包表記の内部でもう一度リスト内包表記を使用する。以下に例を示す。

mul_tbl = [[x * y for x in range(1, 5)] for y in range(1, 4)]
print(mul_tbl)  # [[1, 2, 3, 4], [2, 4, 6, 8], [3, 6, 9, 12]]


 上のコードと同等なコードをfor文で書き下すと次のようになる。

mul_tbl = []
for y in range(1, 4):
    tmp = []
    for x in range(1, 5):
        tmp.append(x * y)
    mul_tbl.append(tmp)

print(mul_tbl)  # [[1, 2, 3, 4], [2, 4, 6, 8], [3, 6, 9, 12]]


 このコードを見ると、結果のリストのリストが3行4列となっている理由が分かるはずだ。つまり、最初のfor文では反復可能オブジェクトがrange(1, 4)となっているので、1〜3の各値が変数yに代入される。外側のfor文は3回実行されるということだ。内側のfor文では反復可能オブジェクトはrange(1, 5)なので、ループは4回実行される。

 よって、外側のループの1回目では、リストtmpには1×1、1×2、1×3、1×4が追加されて、ループの終了時にこの4要素のリストがリストmul_tblに追加される。次のループでは2×1、2×2、2×3、2×4を要素とするリストがmul_tblに追加される。といった具合に処理が行われ、結果として3行4列のリストが作成される。

「解決!Python」のインデックス

解決!Python

Copyright© Digital Advantage Corp. All Rights Reserved.

[an error occurred while processing this directive]
ページトップに戻る