2011-08-09 9 views
12

は、私はこのような何かを行うことができます:スケーラの理解のための怠惰はいつですか? Pythonで

lazy = ((i,j) for i in range(0,10000) for j in range(0,10000)) 
sum((1 for i in lazy)) 

それはしばらく時間がかかりますが、メモリ使用が一定です。 Scalaでは

同じ構造:

(for(i<-0 to 10000; j<-i+1 to 10000) yield (i,j)).count((a:(Int,Int)) => true)

しばらくして、私はそれは遅延評価されるべきにもかかわらず、java.lang.OutOfMemoryErrorを取得します。

答えて

22

Scalaの理解を本質的に怠っているものはありません。それはあなたの2つの範囲の組み合わせが熱心になるという事実を変えない構文的な砂糖*です。

あなたの範囲の怠惰なview秒で作業する場合、理解の結果はあまりにも怠惰になります。

scala> for(i<-(0 to 10000).view; j<-(i+1 to 10000).view) yield (i,j) 
res0: scala.collection.SeqView[(Int, Int),Seq[_]] = SeqViewN(...) 

scala> res0.count((a: (Int, Int)) => true) 
res1: Int = 50005000 

ここで怠惰がために、理解、しかしときflatMapや理由とは何の関係もありませんmap(下記参照)があるタイプのコンテナで呼び出されると、同じタイプのコンテナで結果が返されます。だから、について、理解だけで怠惰(または欠如)を保持されますあなたが入れたものは何でもの


*のようなもののために:。

(0 to 10000).flatMap(i => (i+1 to 10000).map(j => (i, j))) 
+0

"何かのようなものですが、後者の表現は10000001個の要素を返すようですが、50005000ではありません。Whisky tango foxtrot? – Malvolio

+0

@Malvolio注目に感謝! 'j 'は' 1から10000 'ではなく、' i + 1から10000 'まででなければならない。今修正されました。 –

+0

D'oh。私は問題だけでなく、解決策に気づいたはずです。私は引数を無視してマップ関数を見つめていました。 – Malvolio

11

怠惰は、いないため、理解から来ていますしかしコレクション自体から。コレクションの厳密性の特性を調べる必要があります。

しかし、怠け者のために:-)、ここに要約があります:とStreamは厳密ではなく、任意のコレクションのviewの選択された方法です。あなたが怠惰を望むなら、あなたのコレクションを最初に.iterator.viewまたは.toStreamにしてください。

関連する問題