【Python】配列の初期化をわかりやすく解説
はじめに
Pythonで何らかのデータを管理するとき、まず気になるのが配列の初期化ではないでしょうか。
しかし、Pythonには「配列」と呼ばれる構造がいくつか存在します。
たとえば、リストという機能がありますし、用途やパフォーマンスの観点からは**array
モジュール**を使うケースもあります。
さらに、大量の数値データを扱う場合にはNumPyのような外部ライブラリも考えられます。
とはいえ、プログラミング経験が少ない方にとっては、「どれを使えばいいか分からない」「書き方の違いが分かりにくい」といった悩みを抱えてしまうかもしれませんね。
そこで本記事では、リストを中心としたPythonの配列(的な構造)の初期化方法や、内包表記と呼ばれる書き方、2次元配列の扱いなどを分かりやすく解説します。
具体的なコード例を交えながら紹介していきますので、スムーズに理解できるのではないでしょうか。
この記事を読むとわかること
- Pythonで「配列」と呼ばれるリストを使うときの初期化方法
array
モジュールや内包表記を用いた初期化パターン- 2次元配列(リスト)の扱い方と実務での活用イメージ
- リストとタプル、連想配列(辞書型)の違い
- リストを使う上での注意点やよくあるエラー対策
これらを学ぶと、初心者の方でもPythonで複数の値を簡単に取り扱えるようになるでしょう。
さっそく始めていきます。
Pythonにおける配列とは?
Pythonの標準的な機能として、C言語やJavaのような明確な「配列型」はありません。
しかし、複数の要素をまとめて管理したいとき、リストがよく使われます。
リストは要素を順番に保持でき、追加や削除、ソートなどが柔軟に行えるデータ構造です。
要素の型が混在していても問題なく、文字列・数値・ブール値など、あらゆるものを同じリスト内に入れることができます。
一方で、Pythonの標準ライブラリにある**array
モジュール**を使うと、数値専用の配列を表現できます。
このarray
モジュールはメモリ効率が良いと言われることがありますが、用途が限定的です。
大規模な数値演算が必要な場合にはNumPyなどの外部ライブラリが選ばれることが多いでしょう。
とはいえ、ここでは基本的にリストを取り上げて、その初期化方法や実務での使いどころを説明していきたいと思います。
こうしたリストの特徴や使い方を理解しておくと、Pythonでの開発や学習を進める上でとても便利です。
ではさっそく、リストを使った初期化について見ていきましょう。
リストを使った初期化
Pythonで配列的なものを扱うとき、多くの場合はリストを利用します。
リストの基本的な初期化方法
リストは角かっこを使って作ります。
例として、整数をまとめてリストにしたいときは次のように書きます。
numbers = [1, 2, 3, 4, 5]
この段階で、numbers
は5つの要素を持つリストです。
Pythonのリストは変更可能(ミュータブル)なので、後から要素を差し替えたり追加したりできます。
また、空のリストを初期化するときは、単に []
を使います。
empty_list = []
ここに後から値を入れていくパターンも多いです。
複数のリストをまとめる
複数のリストをまとめて作りたい場合も、簡単です。
次のコードを見てみます。
list_a = [1, 2, 3] list_b = [4, 5, 6] merged_list = list_a + list_b
merged_list
は [1, 2, 3, 4, 5, 6]
というリストになります。
リストの結合や連結といった操作が簡潔に書けるのがPythonの魅力です。
初期値を指定してリストを作る
同じ値を一定数だけ持つリストを作りたいときは、繰り返し演算子を利用します。
たとえば、ゼロを10個持つリストを作るのであれば下のように書けます。
zeros = [0] * 10
zeros
は [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
というリストになります。
ループを回さなくても簡単に作れるので便利ですね。
タプルとの違い
Pythonで「複数の値をまとめておく」仕組みとしては、タプルというものも存在します。
タプルはリストとほとんど似ていますが、大きな違いは 要素を変更できない (イミュータブル)という点です。
リストは後から値を変更できるのに対して、タプルは初期化したら要素を差し替えられません。
タプルを使う目的
タプルを使う理由の一つは、固定されたデータを扱うときに安全性を確保できることです。
「この値は途中で変わっては困る」といったケースではタプルを選びます。
また、辞書(後述)のキーとして使える点も見逃せません。
リストはミュータブルな性質を持っているため、そのまま辞書のキーにはできませんが、タプルはイミュータブルなのでキーに利用できるのです。
こうした点を頭に入れておくと、データ構造を選ぶ際に迷いにくくなるかもしれませんね。
タプルの初期化例
タプルを使うときは丸かっこを使います。
points = (10, 20, 30)
このように定義すると points
はタプルとして扱われます。
要素を変更しようとしてもエラーが出るので、「この値は固定して使う」という用途に適しています。
arrayモジュールを使った初期化
Pythonには**array
モジュール**という組み込みライブラリがあります。
これはリストと似ていますが、型を統一して数値だけを効率よく扱うための仕組みです。
arrayモジュールの特徴
- 要素の型が制限される(整数なら整数のみ、浮動小数なら浮動小数のみなど)
- リストに比べてメモリの使用量が少なめ
- 主に低レベルなバイナリ操作が必要な場面で利用される
数値データをバイナリ形式で直接扱いたいときに選ばれます。
ただし、多くの数値計算を要する場合はNumPyを使うケースもあるでしょう。
arrayの初期化例
array
モジュールを使ってみたいときは以下のように書けます。
from array import array # 'i' は符号付き整数を表すタイプコード numbers = array('i', [1, 2, 3, 4, 5])
ここで 'i'
は型コードと呼ばれるものです。
たとえば 'f'
にすれば浮動小数点数の配列を扱えます。
floats = array('f', [1.0, 2.5, 3.7])
数値演算で配列を使いたい場合は、このように array
を活用することができます。
とはいえ、リストと違って型が固定されているので、複数の型を混在させたい場合には向きません。
リスト内包表記とは
リストの初期化方法として、もう一つ便利なテクニックがリスト内包表記です。
これは、リストを作るための式をかっこ内に直接書く手段です。
ループや条件式を簡潔に書けるため、可読性が上がることが多いでしょう。
リスト内包表記の基本
例えば、1から5までの数を2乗したリストを作りたい場合、通常の書き方は次のようになります。
squares = [] for x in range(1, 6): squares.append(x ** 2)
これをリスト内包表記にすると、1行で書けます。
squares = [x ** 2 for x in range(1, 6)]
この書き方はパッと見て「1から5までの数を2乗してリスト化する」という意図が伝わりやすいです。
条件付きのリスト内包表記
リスト内包表記は、条件を加えることもできます。
例えば、1から10までの数のうち偶数だけを取り出してリスト化したいなら、以下のように書きます。
even_numbers = [x for x in range(1, 11) if x % 2 == 0]
even_numbers
は [2, 4, 6, 8, 10]
というリストになります。
同じ処理をループと条件分岐で書くよりも、内包表記の方が読みやすい場合が多いです。
リスト内包表記を使うときの注意点
ただし、内包表記が複雑になりすぎると、かえって可読性が下がる可能性もあります。
条件が多重になったり、ネストしたループが増えたりする場合は、通常のforループで書く方が分かりやすいかもしれません。
こうした点を意識しながら使うと、Python特有の柔軟なコーディングスタイルが楽しめるでしょう。
2次元配列を使った場面
Pythonで2次元配列と呼ばれるものを扱いたい場合は、リストのリストという形で実現します。
2次元配列(リスト)の作り方
例えば、3×3の2次元配列を初期化したいときは次のようなコードが考えられます。
matrix = [ [1, 2, 3], [4, 5, 6], [7, 8, 9] ]
行列のように扱いたい要素を、そのままリストの中にリストとして入れています。
この例では3つのリストがそれぞれ行として並んでおり、matrix[0][0]
は 1
に、matrix[1][2]
は 6
にアクセスできます。
2次元配列のイメージ
2次元データを取り扱う場面といえば、表形式のデータや座標、グリッド状のマップなどが代表的です。
たとえば、座標平面で何らかの情報を格納したいとき、あるいはCSVファイルを読み込んで表データを保持したいときなどがイメージしやすいでしょう。
ネストしたリスト内包表記
2次元のリストも、リスト内包表記を使うとコンパクトに書けます。
例えば、すべて0で埋めた3×3のリストを作るなら以下のようになります。
matrix_zeros = [[0 for _ in range(3)] for _ in range(3)]
変数名はアンダースコア _
を使っていますが、これは「この変数は使わない」という合図としてよく利用される書き方です。
こうして2次元配列を初期化しておけば、簡単に任意の要素へアクセスできます。
連想配列(辞書型)との比較
Pythonでは、キーと値をセットで管理する**辞書(dict
)**型もよく使われます。
これは「連想配列」と呼ばれるデータ構造に相当します。
リストと辞書の使い分け
リストはインデックス(0, 1, 2, ...)で要素を管理します。
一方で辞書は、数値以外にも文字列やタプルなどをキーとして使えます。
たとえば、ユーザー情報を扱うときに「名前」「年齢」「住所」などをキーにして値を管理したいなら、辞書の方が直感的でしょう。
user_info = { "name": "Alice", "age": 30, "city": "Tokyo" }
こうしておけば、user_info["name"]
で名前の情報に直接アクセスできます。
リストだと user_info[0]
といったふうに番号で取り出すことになり、何が入っているのか把握しづらくなるかもしれません。
初心者が混乱しやすいポイント
リストや配列と言われると、どうしても「インデックスがあるもの」と頭に浮かびがちです。
しかし、連想配列(辞書)を使うと文字列キーによって管理できるため、コードが読みやすくなるケースがあります。
どんな用途で何を管理したいのかを考えたうえで、リストか辞書かを選ぶとよいでしょう。
リストのメモリ効率と実行速度
Pythonのリストは、要素を追加・削除するときに柔軟に動くため、内部的にはポインタ参照のような仕組みで要素を持っています。
要素数が膨大になると、追加や削除、検索のコストが気になるかもしれません。
とはいえ、Pythonを一般的な用途で使う分には、リストのパフォーマンスが大きな問題になることはそれほど多くはないでしょう。
大量データを扱う場合
数万、数十万という規模の数値データを扱う場合は、前述の**array
モジュールあるいはNumPy**を検討することがあります。
これらを使うと、メモリ効率や実行速度の面で利点があります。
ただし、単に文字列のリストを少し操作するくらいなら、リストでまったく問題ありません。
実行速度をざっくりと理解する
- リストの末尾に要素を追加する
append
は平均的に高速 - 要素の検索はリストの長さに比例して遅くなる可能性がある
- ソートは内部で高度に最適化されているが、やはり要素数が多すぎると時間がかかる
こうした特徴を踏まえながら、必要に応じてデータ構造を選ぶとよいですね。
実務での活用シーン
実務では、リストを初期化して使う場面は至るところにあるでしょう。
たとえば、Webアプリケーションでフォームの入力値を一時的にリストとして保管したり、ログ解析で取得したエラーメッセージの一覧を管理したりするケースが考えられます。
配列の初期化を活用する一例
以下は、ユーザーから投稿されたコメントをまとめて格納しておくイメージを示したものです。
comments = [] comments.append("こんにちは") comments.append("記事がとても参考になりました") comments.append("ありがとうございます") # 後でコメント数を表示する print(len(comments))
このように append
を使うと動的にリストへ追加できるので、フォーム入力や外部APIから取得したデータをどんどん格納する場合に役立ちます。
CSVデータを読み込んでリスト化
実務では、CSVファイルなどから読み込んだデータを行ごとにリストとして管理するケースもあります。
イメージとしては以下のようなコードになります。
import csv with open('sample.csv', 'r', encoding='utf-8') as f: reader = csv.reader(f) data_list = [row for row in reader] # row はリスト
data_list
は2次元リストとして扱えるので、あとは要素の加工や集計に活用できます。
こういった作業は初心者の方でも取り組みやすいので、「リストをどんなふうに役立てられるのか」をイメージするきっかけになるかもしれません。
よくあるエラーと対策
リストを使っていると、初心者の方が遭遇しがちなエラーや落とし穴がいくつかあります。
ここでは代表的なものをまとめてみましょう。
インデックス範囲外エラー
リストにアクセスするときに、存在しないインデックスを指定してしまうとエラーになります。
numbers = [1, 2, 3] print(numbers[5]) # IndexError
このように、リストの範囲外を参照すると IndexError
が出るので注意です。
アクセスする前に len()
でリストの長さを確認したり、条件式でチェックしたりするのが一般的な対策です。
ミュータブルなリストの意図しない変更
リストを変数間で使いまわすとき、同じリストオブジェクトを参照している場合は注意が必要です。
a = [1, 2, 3] b = a b[0] = 100 print(a) # [100, 2, 3] aも変更されている
このように、同じリストを参照していると、片方を変更したときにもう片方にも影響が及びます。
必要に応じて copy()
メソッドやスライスを使ってコピーを作ると良いでしょう。
a = [1, 2, 3] b = a.copy() b[0] = 100 print(a) # [1, 2, 3] こちらは変わらない
リストと文字列の混同
リストと文字列は見た目が似ている部分もありますが、扱い方が違います。
たとえば文字列をリストに変換したいときは list()
を使うと、文字単位のリストに展開されます。
意図していない場合は混乱しないようにしましょう。
text = "Hello" list_text = list(text) # ['H', 'e', 'l', 'l', 'o']
こうした点を理解しておけば、うっかりバグを避けられるでしょう。
リストを初期化するとき、何度も同じリストを使い回すかどうかを事前に整理しておくとトラブルを防ぎやすいです。
まとめ
ここまで、Pythonの配列の初期化についてリストを中心に解説してきました。
リストは柔軟性が高く、多くの場面で使われる主要なデータ構造です。
しかしながら、用途によってはタプルやarray
モジュール、あるいは辞書を使うほうが分かりやすい場合もあります。
それぞれの特徴をしっかり把握し、状況に合った方法を選ぶと、コードの保守性や可読性が向上しやすいのではないでしょうか。
- リストは角かっこ
[ ]
を使って初期化 - タプルは丸かっこ
( )
でイミュータブルなデータを保持 array
モジュールは型を揃えて数値を扱うときに適する- リスト内包表記は複雑な処理をコンパクトに表現できる
- 2次元配列はリストのリストで表現
- 辞書型は連想配列として文字列キーでデータ管理が可能
Pythonの配列まわりで悩むことが少なくなれば、もっと開発に集中しやすくなるでしょう。
ぜひ本記事で紹介した内容を踏まえて、ご自身のプロジェクトでもうまく活用してみてください。