2016-04-27 11 views
1

Rubyの経験を持ちながら、私はPythonを学び、リスト変換技術(select/map/reduce)をPythonにマップしました。 私はリスト[0..99]を取り、正方形の偶数を取り出して要約したいとしましょう。 PythonでPythonのRubyと比較した処理リスト

:これまでのところ、それは罰金と慣用的に見えるPythonでRubyの

(0..99) 
    .select {|num| num % 2 == 0} 
    .map {|num| num*num} 
    .inject {|sum, n| sum + n} 

arr = range(100) 
res = [x*x for x in arr if x % 2 == 0] 
res = reduce(lambda x,y: x+y, res) 

。 ここで、偶数を四角形にした後、10で割り切れるものを100で割った後、奇数を選択したいというマッピング/フィルタリングを追加したいとしましょう。それはにうまくスケールRubyでは

:Pythonでは、コードはそうのようになって

(0..99) 
    .select {|num| num % 2 == 0} 
    .map {|num| num*num} 
    .select {|num| num % 10 == 0} 
    .map {|num| num/100} 
    .select {|num| num % 2 != 0} 
    .inject {|sum, n| sum + n} 

arr = range(100) 
res = [x*x for x in arr if x % 2 == 0] 
res = [x for x in res if x % 100 == 0] 
res = [x/100 for x in res] 
res = [x for x in res if x % 2 != 0] 
res = reduce(lambda x,y: x+y, res) 
それはここでPythonのコードのように感じている(私は巣でし効率的ではない慣用とではありません

それは読めなくなるだろう)。 また、Rubyのコードは、Pythonコードについて言えない怠惰な評価のために簡単に修正することができます。 このアイデアとよく読みやすく効率的なコードをPythonでどのように表現すればよいですか?

+0

2番目の例は、最初の例よりも慣用で効率的ではありません。彼らは私とほぼ同じように見えます。 – Kwarrtz

+0

@Kwarrtzストリームの連鎖を壊し、各ステップを変数に割り当てるということは、それが慣用的で効率的ではないことです。これにより、インタプリタ(IMHO)がコードを最適化できないようにする必要があります。しかし、私はここでちょうど推測しています。 – Andrei

+1

うまくいけば、内包物はその問題を解決するはずです。 – Kwarrtz

答えて

2

誰もが読めるコードの定義が異なります。個人的に、私は(少なくとも1つのライナーのために)これはかなり読みやすいことがわかり、不要な内包の多くを削減します。

sum([(x*x)/100 for x in range(100) if not x*x % 100 and (x*x)/100 % 2]) 

あなたはいくつかのより多くの本をクリーンアップすることができます:

f = lambda x: (x*x)/100 
sum([f(x) for x in range(100) if not x*x % 100 and f(x) % 2]) 

これがあるとその質問の中の1つの補足よりも10文字余分に長いかもしれません。 6行を2つに減らし、4つのリスト内包を単一の理解に減らします。

+0

良い例、ありがとう!たぶん私の例は少し工夫されたかもしれませんが、私が指摘するところは、ますます多くのフィルタリング/マッピングを追加し続けると、すぐに最適化するのが難しくなります。 – Andrei

関連する問題