リスト内包表記
リスト内包表記が便利
map()関数の代わりになるのが、for文と、今回のリスト内包表記。とくに、リスト内包表記は直感的にも非常にわかりやすいです。
以下にmap()関数とリスト内包表記について比較しています。
[適用したい関数(要素) for 要素 in 配列]
filter()関数の機能も組み合わせることができる
更に、filter()関数の機能も追加することが出来ます。構造は以下です。
[適用したい関数(要素) for 要素 in フィルタにかける配列 if 条件]
filter()関数とリスト内包表記で比較してみましょう。filter関数の場合はlambda式で条件を記述しますが、リスト内包表記の場合は関数定義ではなく、リスト内包表記内部で条件を記述します。
lambda式の三項演算子と似ていますが、if ~ else ~ と書かないのがミソ。つまり、条件を満たさないelse〜が不要で、条件を満たさないものはデフォルトで無視されます。
zip()関数による複数変数ループ
リスト内包表記では一つの変数におけるループ処理を説明しましたが、以下は複数配列をループさせるための記述法です。
for x, y in zip(a, b)
上の構造では、配列a, bについてx, yの配列データを出力します。
百聞は一見に如かずですね。コードを記載してみます。
配列データの部分にzip()関数を使うことで、複数配列でのループ処理を行うことが出来ます。
ループの中にループを記述=多重ループ
for文など、ループの中にループを記述する方法があります。これを多重ループといいます。
イメージとしては、以下のような形。xのループの中に、yのループを入れます。
for文と同様に、リスト内包表記でも多重ループが可能です。以下の構造です。
[[x, y] for x in a for y in b]
例えば、for文ならびにリスト内包表記の多重ループは下記のようなコードになります。
「map()関数→list()関数で配列作成」は時間がかかる!?
なに?map()には弱点がある、って??
map()関数は、map型のイテレータを作成するもの。
- イテレータとは、「データの流れを表現している」オブジェクト
- オブジェクトとは、プログラム上のふんわりした”モノ”をひとまとめに表現した言葉。
- オブジェクトは、クラス(設計図)とかインスタンス(実際に作ったモノ)とか、色々と含んだふんわりした表現。
イテレータというのは「データの流れを指示する」オブジェクト。
仮に以下を実行するとどうなるか。Aidemyで使っている環境で走らせてみると、print(map())の出力結果がコンソールに出力されています。何やらリスト型ではなく、変な数字(イテレータ)が出ていますよね。
なので、正しくはa=list(map(hr_min),minute_data))として配列を生成し、print(a)で出力します。
イテレータ情報をlist()関数で読み、配列を生成するのに時間がかかるらしい。
だけど、どれくらい違うんだぁー?
試してみてもいいが、Aidemyのチュータさんに聞いてみちゃえ!
以下のように聞きたいときにSlackで聞くことが出来ます。
実は、手元の環境ではmap()関数の方がリスト内包表記より早かったです。
なので、あまりmap()関数が遅いとか気にしなくて問題ないです。
ということで、map()関数が遅いとか気にしなくてよいということがわかりました。
いやぁ〜、わからないときにチュータさんにすぐ聞けるのは嬉しいよね〜♪