問題設定
想定しているのは、たとえばこんなシチュエーションです。
s = "hoge! 1234" tmp = s.split() lst = [tmp[0], int(tmp[1])]
要するに、比較的短いリストだが性質の違うものが入っており、それぞれ違う処理をして返したいのです。
それだけなら良いのですが、上の例だとs.split()の結果を一時変数に入れないとどうしようもないので(二回呼ぶと再計算されてしまう)、まどろっこしいことになります。ここでリスト内包を使おうとしても、まともな処理は書けません(ん、zipでlambdaと一緒に回せばできなくはないか)。
(私が思いつく)解決策は2つあります。どちらも関数を使います。
解決策1:愚直に関数定義
関数の引数に渡せばローカル変数として束縛されるので、できるという考え方です。
def f(x): return [x[0], int(x[1])] s = "hoge! 1234" lst = f(s.split())
もういっそsを渡す関数にした方が素直ですが、趣旨からずれるのでNG。
この方法は記述が短くならないという欠点があります。
解決策2:lambda
lispのletと同じテクニックで一時変数を束縛しています。
s = "hoge! 1234" lst = (lambda t:[t[0], int(t[1])])(s.split())
とても短く書け、簡潔な記述です。可読性は人によって異なると思いますが、個人的には読みづらいと思います。
まとめ
このテクニックはリスト内包表記の中でどうしても一時変数が必要になったときに使えます。覚えておいて損はないです。