はじめに
Pythonの内包表記は、Python独特の書き方として有名(?)だと思います。
今回は、そんな内包表記の基本的な部分についてまとめていきます。
具体的には、リスト内包表記、ジェネレータ式についてです。
リスト内包表記
リスト内包表記は特に有名かと思います。
print([i for i in range(0, 10)])
たったこれだけで0から9までの数字が格納されたリストが出力されます。
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
とても簡単に作れちゃいますね。
もちろん、もっと色々なことが可能です。
print('¥n'.join(['FizzBuzz' if i%15 == 0 else
'Fizz' if i%3 == 0 else
'Buzz' if i%5 == 0 else
str(i) for i in range(1, 101)]))
これはFizzBuzzですね。新しい言語を勉強し始めたら最初にやるやつ。
1から100までの数字を順に表示していき、3の倍数ならFizz、5の倍数ならBuzz、3の倍数かつ5の倍数ならFizzBuzzを数字の代わりに表示するものです。
ちなみに実行すると、1から100までを一つひとつ改行して表示します。
'¥n'.joinの部分がそれにあたりますね。
というか、自分で書いておいていうのも何ですが、かなり強引なコードですね……。
これはですね、次にもっと良い書き方を紹介するので、あえてこんな感じで書いています。
それでは次に行きましょう。
ジェネレータ式
ジェネレータ式……難しそうな言葉が登場しましたね……。
ジェネレータ式が何なのかを詳しく説明するには、ジェネレータとは何かを説明しなければならず、さらにジェネラータを説明するためにはイテレータについて説明しなければならなず、さらにイテレータを説明すqsうぇdrftgyふじこlp;@:(今度別の記事として投稿するかもです)
簡単に言うと、括弧内でさっと関数をつくってさっと使えちゃう便利なやつです。
print(i for i in range(0,10))
さっきのリスト内包表記とほぼ同じように感じますね。
違いは[ ]がないことですね。
この時、一体どのようにして出力されるのでしょうか?
<generator object <genexpr> at 0x10d747b48>
出力はこちら。
さっきのリストとは全然違いますね!
これでは意味が全くわかりませんので、内包表記で書くときは[ ]を忘れないようにしてくださいね。
しかしながら、このジェネレータ式が便利な時も結構多いのです。
print('¥n'.join((i%3 == 0)*'Fizz' + (i%5 == 0)*'Buzz' or str(i) for i in range(1, 101)))
はい。一行の情報量がかなり多い気がしますが、一行で何かのコードが書かれましたね。
お察しの通り、これはFizzBuzzです。
出力も、先ほどと全く同じ形式で出力されます。
こんな書き方、リスト内包表記ではできませんね!(ですよね?)
リスト内包表記の上のコードでも無理やり1行にできますが……見にくいのは嫌ですよね。
(リスト内包表記もジェネレータ式も80文字超えちゃうので実際には改行が必要です)
感想
今回は2種類のみの紹介になりましたが、これだけもかなり色々できそうですよね!
何より内包表記を使うとPythonicなコードっぽくて好きです。
あとは、ジェネレータ式が使えそうなところは積極的に使ったほうがいいと思います。リスト内包表記だといちいちリスト作っちゃうので。
以上です。
追記(2015/12/2)
print('¥n'.join((i%3 == 0)*'Fizz' + (i%5 == 0)*'Buzz' or str(i) for i in range(1, 101)))
こんな書き方、リスト内包表記ではできませんね!(ですよね?)
申し訳ありません、できます。
print('¥n'.join([(i%3 == 0)*'Fizz' + (i%5 == 0)*'Buzz' or str(i) for i in range(1, 101)]))
これでも全く同じ出力が得られます。
ここ間違えちゃいけないだろってところを盛大に間違えてしまい、この記事の目的が完全に失われたような気さえしますね……。
以後気をつけます。