読者です 読者をやめる 読者になる 読者になる

When it’s ready.

出来るまで出来ない

Pythonリスト内包表記文法 低速マスター

リスト内包表記(LC)使った方が圧倒的にコードが読みやすく、短くなる。慣れてないという理由で使われてない気がするので今後の自分のためにも、メモを残す。

LCは基本的に、ListやHashを処理する際に使用される。例えば、規則性のある並びのListが欲しい時などに利用すると良い。

1, 基礎

リストの作成

forの前が処理、forからList名までがひとつのforの段落で前から評価される。

src_list = [1,2,3,4,5]
print [x for x in src_list]
# [1,2,3,4,5]
リストの作成2

for部で取り出された要素が、その後ろif部で評価され真だったものだけが、初めのx*2に渡され処理される(この場合は、2.4だけ)

src_list = [1,2,3,4,5]
print [x*2 for x in src_list if x % 2 == 0]
# [4,8]
リストの作成3

一つ目のforで取り出されたlistが二つ目のforに渡され展開された結果が、先頭の処理部分に渡される。

X = [[10, 20], [11, 21], [12, 22], [13, 23], [14, 24], [15, 25], [16, 26], [17, 27], [18, 28], [19, 29]]
[i for ii in X for i in ii]
# [10, 20, 11, 21, 12, 22, 13, 23, 14, 24, 15, 25, 16, 26, 17, 27, 18, 28, 19, 29]

2,応用

渡された文字列を4文字ずつリストに分けなさい

s = 'abcdefghijklmnopqrstuvwxyz'
[s[i:i+4] for i in range(0, len(s), 4)]
# ['abcd', 'efgh', 'ijkl', 'mnop', 'qrst', 'uvwx', 'yz']
#4文字だけ欲しい場合は
[s[i:i+4] for i in range(0, len(s), 4) if len(s[i:i+4]) == 4]
# ['abcd', 'efgh', 'ijkl', 'mnop', 'qrst', 'uvwx']

要素二つのListAのList、Xがあります。ListAの前後を入れ替えなさい。

X = [[10, 20], [11, 21], [12, 22], [13, 23], [14, 24], [15, 25], [16, 26], [17, 27], [18, 28], [19, 29]]
[[x[1], x[0]] for x in X]
# [[20, 10], [21, 11], [22, 12], [23, 13], [24, 14], [25, 15], [26, 16], [27, 17], [28, 18], [29, 19]]

追記、こんなのも出来る
ビンゴカードプログラム、5x5の配列で各行には1-75の数字を15きざみでランダムに格納する

import random
[(lambda xs: random.shuffle(xs) or xs)(xs)[0:5] for xs in [range(1,76)[i:][:15] for i in range(0,75,15)]]
# [[13, 1, 7, 8, 9], [30, 16, 22, 21, 25], [42, 36, 33, 35, 31], [50, 47, 60, 52, 49], [65, 67, 72, 75, 63]]

配列を返さなくても必要なだけ処理をさせる時にもforを書かずに済ませられる
0.2秒ずつ停止を10回繰り返す(トータル2秒停止する)

from time import sleep
[sleep(0.2) or x for x in range(10)]
#2秒停止したのち
#[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

例題を考えるのがムズイ

FizzBuzかけるのかな?

追記:id:surgoさまよりFizzBuzzの解答例を教えてもらいました。ありがとうございます。

[(i%3==0 and 1 or 0)*"Fizz"+(i%5==0 and 1 or 0)*"Buzz" or i for i in range(1, 100)]

最後列のifをどう組むかをどうするのか考えていたのですがこの方法は、リターンされた文字をもとにどう返すのか決めています。このやり方はいろんなところで使えそう。


if hoge else foo みたいな処理をさせるにはどうすれば良いんだろ?



良くやりそうなforの処理は、40%くらいLCで書き直せそう。