🧑🎓
【覚書】Pythonとリスト内包表記とLINQ
リスト内包表記とは
for
を展開して配列を作る式、みたいな感じ。
C#のLINQ的な感じです。
Pythonなら
na = [v*2 for v in a]
配列aに対して、forの後のvでイテレーション保存して、forの前のv*2の値が戻り値になって、それが配列分繰り返す…。
というところ。
C#なら
na = a.Select(v => v * 2).ToArray();
かな。
Where
制限をかけるときはどうするのか。
C#なら
表題の通り、Whereを使います。
var a = new []
{
new {id = 1, is_star = true, star = 3},
new {id = 2, is_star = true, star = 5},
new {id = 3, is_star = false, star = 0},
new {id = 4, is_star = true, star = 2},
};
var na = a.Where(v => v.is_star).Select(v => v.star).ToArray();
余談として、C#ではクエリ構文でも書ける。
na = (
from v in a
where v.is_star
select v.star
).ToArray();
Pythonなら
後置ifです。
a = [
{"id": 1, "is_star": True, "star": 3},
{"id": 2, "is_star": True, "star": 5},
{"id": 3, "is_star": False, "star": 0},
{"id": 4, "is_star": True, "star": 2},
]
na = [v["star"] for v in a if v["is_star"]]
2段Select
これが一番書きたかったこと。
C#なら
SelectMany
からの。
var a = new[]
{
new {id = 1, is_avail = true, content = new[] {
new {id = 100, is_star = true, star = 5},
new {id = 101, is_star = false, star = 0},
new {id = 102, is_star = true, star = 1},
new {id = 103, is_star = true, star = 3},
}},
new {id = 2, is_avail = true, content = new[] {
new {id = 100, is_star = true, star = 4},
new {id = 101, is_star = false, star = 0},
new {id = 102, is_star = false, star = 0},
new {id = 103, is_star = true, star = 2},
}},
new {id = 3, is_avail = false, content = new[] {
new {id = 100, is_star = true, star = 4},
new {id = 101, is_star = true, star = 2},
new {id = 102, is_star = false, star = 1},
new {id = 103, is_star = true, star = 3},
}},
new {id = 4, is_avail = true, content = new[] {
new {id = 100, is_star = true, star = 5},
new {id = 101, is_star = true, star = 2},
new {id = 102, is_star = true, star = 1},
new {id = 103, is_star = false, star = 0},
}},
};
var na = a
.Where(v => v.is_avail)
.SelectMany(v => v.content)
.Where(v => v.is_star)
.Select(v => v.star)
.ToArray();
Pythonなら
なんかとっても変。
a = [
{"id":1, "is_avail":True, "content": [
{"id":100, "is_star": True, "star": 5},
{"id":101, "is_star": False, "star": 0},
{"id":102, "is_star": True, "star": 1},
{"id":103, "is_star": True, "star": 3},
]},
{"id":2, "is_avail":True, "content": [
{"id":100, "is_star": True, "star": 4},
{"id":101, "is_star": False, "star": 0},
{"id":102, "is_star": False, "star": 0},
{"id":103, "is_star": True, "star": 2},
]},
{"id":3, "is_avail":False, "content": [
{"id":100, "is_star": True, "star": 4},
{"id":101, "is_star": True, "star": 2},
{"id":102, "is_star": False, "star": 1},
{"id":103, "is_star": True, "star": 3},
]},
{"id":4, "is_avail":True, "content": [
{"id":100, "is_star": True, "star": 5},
{"id":101, "is_star": True, "star": 2},
{"id":102, "is_star": True, "star": 1},
{"id":103, "is_star": False, "star": 0},
]},
]
na = [v["star"] for v1 in a if v1["is_avail"] for v in v1["content"] if v["is_star"]]
1ライナーで書けるのは楽しいんだが、読みにくいこと甚だしい。
見方としては、for
と if
のフローがコード通りに並んでいるだけ、になる。
for v1 in a if v1["is_avail"] for v in v1["content"] if v["is_star"]
ここんところは、つまりはこう書くとわかりやすい。
na = []
for v1 in a:
if v1["is_avail"]:
for v in v1["content"]:
if v["is_star"]:
na.append(v["star"])
:を抜いてずらずら書いてあるだけ。
そして一番中のforループで使用されている変数が一番前に出てきて処理される最終変数になって、[]で配列になる。
この理屈さえ分かっていれば、 何段だろうが恐いもん無し である。
あ、いや、読みにくさが恐い。
Discussion