小编ste*_*red的帖子

Scala,Erastothenes:有一种直接用迭代替换流的方法吗?

我写了一个函数,使用流无限期地生成质数(维基百科:Erastothenes的增量筛).它返回一个流,但它也在内部合并素数倍流以标记即将到来的复合.如果我自己这样说,这个定义简洁,实用,优雅且易于理解:

def primes(): Stream[Int] = {
  def merge(a: Stream[Int], b: Stream[Int]): Stream[Int] = {
    def next = a.head min b.head
    Stream.cons(next, merge(if (a.head == next) a.tail else a,
                            if (b.head == next) b.tail else b))
  }
  def test(n: Int, compositeStream: Stream[Int]): Stream[Int] = {
    if (n == compositeStream.head) test(n+1, compositeStream.tail)
    else Stream.cons(n, test(n+1, merge(compositeStream, Stream.from(n*n, n))))
  }
  test(2, Stream.from(4, 2))
}
Run Code Online (Sandbox Code Playgroud)

但是,当我尝试生成第1000个素数时,我得到了"java.lang.OutOfMemoryError:超出GC开销限制".

我有一个替代解决方案,它在primes上返回一个迭代器,并在内部使用元组的优先级队列(multiple,prime用于生成多个)来标记即将到来的复合.它运行良好,但它需要大约两倍的代码,我基本上不得不从头重新开始:

import scala.collection.mutable.PriorityQueue
def primes(): Iterator[Int] = {
  // Tuple (composite, prime) is used to generate …
Run Code Online (Sandbox Code Playgroud)

primes iterator scala stream out-of-memory

9
推荐指数
3
解决办法
1287
查看次数

Scala:导入如何防止发现隐含值?

我可以使用调试隐式的建议:

我想使用隐含的,x:

type T
trait HasT {
  implicit def x: T = ...
}
Run Code Online (Sandbox Code Playgroud)

但我还需要从某个包中导入通配符foo.我尝试了两种不同的方式来介绍两者:

class UseT extends HasT {
  import foo._
  implicitly[T] // fails! "could not find implicit value"
  // use foo stuff
}
Run Code Online (Sandbox Code Playgroud)

class UseT {
  object hasT extends HasT
  import hasT.x
  import foo._
  implicitly[T] // fails! "could not find implicit value"
}
Run Code Online (Sandbox Code Playgroud)

两者都失败了"找不到"(不是"模糊的含义值").

x: T通过继承或导入在方法调用点访问隐式标识符时会发生这种情况.

我的解决方法是在导入之前将x重新绑定到隐式val.以下两项工作:

implicit val x2: T = implicitly[T]
import foo._
implicitly[T] // works!
Run Code Online (Sandbox Code Playgroud)

implicit val …
Run Code Online (Sandbox Code Playgroud)

scope scala shadowing implicits slick

9
推荐指数
1
解决办法
900
查看次数

Python:是否有语法级支持解压缩,从元组,到*anonymous*函数的参数?

假设我们有以下内容:

args = (4,7,5)
def foo(a,b,c): return a*b%c
Run Code Online (Sandbox Code Playgroud)

Python方便地允许元组解包:

foo(4,7,5)             # returns 3
foo(*args)             # returns foo(4,7,5), i.e. 3
Run Code Online (Sandbox Code Playgroud)

所以我们不必这样做:

foo(t[0], t[1], t[2])  # a repulsive, verbose, and error-prone synonym
Run Code Online (Sandbox Code Playgroud)

现在假设我们有一个类似的3元组列表,并希望列出foo(t)每个元组的列表t.有"一种明显的方法":

list(map(lambda t: foo(*t), listoftuples))
Run Code Online (Sandbox Code Playgroud)

但现在假设foo只是一个扔掉的功能.我们不希望垃圾污染我们的命名空间.让我们在匿名的地毯下扫一扫!:

list(map(lambda t: (lambda a, b, c: a*b%c)(*t), listoftuples))
Run Code Online (Sandbox Code Playgroud)

好吧,我们现在有嵌套的lambda.当然,我们可以解析它.但是我们冒着被误认为是一个阴谋家的风险,这个阴谋家喜欢构造神秘的法术,其唯一目的就是为那些冒昧的人重新审视我们的代码.

此外,对于这样一个简单的想法,这有点冗长.这似乎不是pythonic.(在scala中,相当于内部lambda (_*_%_),假设上下文允许类型推断.如果这 pythonic,它不会同样简洁吗?).

我们可以这样删除内部lambda:

list(map((lambda t: t[0] * t[1] % t[2]), listoftuples))
Run Code Online (Sandbox Code Playgroud)

那更短,但令人厌恶.我发现使用幻数(而不是名称)来引用参数往往会导致错误.

如果它看起来更像这样会很棒:

list(map((lambda a, b, c: a*b%c), listoftuples))
Run Code Online (Sandbox Code Playgroud)

当然,它不可能.这就像打电话一样foo(args).我们需要一个星号,可以这么说.这是一个可能的星号:

def unpackInto(func): return lambda …
Run Code Online (Sandbox Code Playgroud)

python lambda coding-style language-design iterable-unpacking

3
推荐指数
2
解决办法
997
查看次数