紙の辞書を触る機会ってめっきりなくなったなぁ……

おまとめ三行

Pythonでは配列のことをリストと呼ぶ
連想配列はディクショナリ(辞書)
こちらが望む通りの順番になるとは限らない
今日は配列について基本的なところを見ていきましょう。PHPと同じ感覚でやろうとすると意外と上手くいかない部分があるので、慣れるまではちょっともどかしいかも。



基本的な配列

Pythonでは配列のことをリストと呼ぶらしいです。こっから先、配列とリストって言葉が入り混じってごっちゃになっちゃうかもですが、同じものを示してると思ってください。

とりあえずシンプルなリストを作成してみましょう。

//PHP
$array = array(1,2,3,4,5);

#Python
array = [1,2,3,4,5]

Pythonでは[]でリストを作成します。まあPHPもarray()ではなく[]で配列を作成できますから、特に違和感はないかと。

出力のしかたは同じです。先頭の要素を0番として考えるのも一緒。

//PHP
echo $array[0];

#Python
print(array[0])

PHPと大きく違うのは、このリストはキーを指定できません。連想配列はもちろん、数字のキーを振ることもできない。

array = [1 => 1, 2 => 2]

例えばこんな風に書いてもエラーになる。Pythonの場合、連想配列でも「=>」は使わないのですが、正しいキーの書き方をしてもリストだとエラーになるので注意っす。



連想配列

じゃあ連想配列はどう書くかって話ですが、Pythonではディクショナリ(辞書)という機能があります。

//PHP
$array = array('a' => 1, 'b' => 2);

#Python
array = {'a':1, 'b':2}

ディクショナリは[]ではなく{}というかっこを使います。キーと要素をつなぐ文字は「=>」ではなく「:」になります。PHPの配列よりはJSONに近い感覚ですかね。

出力はリストと同じで大丈夫です。

//PHP
echo $array['a'];

#Python
print(array['a'])

PHPは配列も連想配列もarray()や[]で良いので、キーを省略すれば自動的に数字の0からキーが振られていきますが、ディクショナリはキーを省略したからといってリスト扱いにはなってくれません。それどころかディクショナリ型ですらなくなってしまいます。集合型という型になるのですが、それは今回は置いときましょう。

「array[0]」みたいな書き方もできなくなります。インデックスがないぞってエラーになる。

#エラーになる
array = {1,2,3,4,5}
print(array[0])



要素の順番を保持したい

要素を追加した場合、PHPの連想配列は要素を追加した順に並んでくれますが、Pythonだと必ずしもそうなるとは限りません。どうやら追加した順番を保持しておく機能が通常のディクショナリにはないようです。辞書なのに五十音順やアルファベット順も保持しないとは……。

//PHP
$array = array('a' => 1, 'b' => 2);
$array['c'] = 3
print_r($array);

//出力結果(必ずこの順番で出力される)
Array([a] => 1 [b] => 2 [c] => 3)

#Python
array = {'a':1,'b':2}
array['c'] = 0
print(array)

#出力結果(順番が入れ替わることがある)
{'b': 2, 'c': 0, 'a': 1}

上記では「b,c,a」の順番で表示されたとしていますが、必ずこうなるというわけではないです。cが先頭になる場合もあれば、「a,b,c」の順番通りになる場合もある。とにかくこちらが望む通りの順番になるとは限らないってことですね。ループ処理などをする時に順番が変わってて思わぬ結果になる場合があるかもしれない。

じゃあ保持するにはどうするかってーと「OrderedDict」というディクショナリを使います。

import collections
a = collections.OrderedDict()
a['a'] = 1
a['b'] = 2
a['c'] = 0

これだと「a,b,c」の順番が保持されます。



変数は最初に定義する

これは僕がよくうっかりやっちゃうって話なのですが、PHPはいきなり配列に値を追加できます。でもPythonはそうはいきません。

//PHP(エラーにならない)
$array[0] = 1;
$array['a'] = 1;#Python(エラーになる)
array[0] = 1
array['a'] = 1

リストにしろディクショナリにしろ、要素を追加したければ最初に変数を定義しておかないといけない。

#リスト
array = []
array.append(1)

#ディクショナリ
array = {}
array['a'] = 1

PythonはPHPよりも型に厳しいですからね。変数の型が未定義だとダメってことなんでしょうか。

また今度改めてやりますが、リストの方は「array[0] = 1」みたいな書き方で要素の追加ができません。上記のように「append」という機能を使って追加します。



多次元配列

これは僕もちょっと使いこなせていないところがありまして……むしろ誰かにアドバイスをいただきたいのですが、多次元配列はPHPに比べるとちょいとややこしい感じがします。

さっきみたいに最初にリストやディクショナリを定義しておけば多次元もできるのかというと、残念ながらエラーになってしまいます。一つ下の階層でもっかい定義すればエラーにはならない。

#エラーになる
array = {}
array[0][0] = 1

#エラーにならない
array = {}
array[0] = {}
array[0][0] = 1

PHPだとこういうのは必要ないので、何かこう、もうちょっと簡単にやらせてくれよって思いたくなっちゃうような気がしないでもないです。

まあ、これくらいきっちりしてた方が、意図せず変なところに変な値が入っちゃうのは防ぎやすいのかもしれませんね。そんなことないか?



内包表記

Pythonのリストや辞書には内包表記と呼ばれる機能があります。簡単に言うとリストの中でもfor文やif文などが使えるような機能です。PHPにはない機能ですね。

例えばこんな風にリストや辞書を作成できる。

#リストを作成
array = [i for i in range(5)]
print(array)

#出力結果
[0, 1, 2, 3, 4]

#辞書を作成
array = {i + 1 : (i + 1) * 2 for i in range(5)}
print(array)

#出力結果
{1: 2, 2: 4, 3: 6, 4: 8, 5: 10}

どういう場面で重宝されるかって言われるとまだよく分かってないんですけど、でも何となく便利な機能のような気がする。

ちなみに通常のfor文とappend()を使ってリストを作成したりするよりも、内包表記の方が処理速度が速いらしいです。知っておいて損はないでしょう。

Pythonのfor文やrange()についてはまた別の機会に。






基本はこんなもんでしょうか。もっと詳細にキーや要素を操作するのは次回以降にじっくり見ていきましょう。

ほんじゃあ今日はこん辺で。次回もこのチャンネルでよろしくよろしこ。



その他のPythonを少し触ってみたの記事はこちら
前書きと索引的な