是否可以在Scala中实现与Pythonyield
语句等效的功能,在该语句中它记住使用该函数的局部状态,并在每次调用该函数时“产生”下一个值?
我希望有类似这样的东西可以将递归函数转换为迭代器。有点像这样:
# this is python
def foo(i):
yield i
if i > 0:
for j in foo(i - 1):
yield j
for i in foo(5):
print i
除此以外,foo
可能会更复杂并通过一些非循环对象图重复出现。
附加编辑: 让我添加一个更复杂的示例(但仍然很简单):我可以编写一个简单的递归函数,以进行打印:
// this is Scala
def printClass(clazz:Class[_], indent:String=""): Unit = {
clazz match {
case null =>
case _ =>
println(indent + clazz)
printClass(clazz.getSuperclass, indent + " ")
for (c <- clazz.getInterfaces) {
printClass(c, indent + " ")
}
}
}
理想情况下,我希望拥有一个可以轻松更改一些语句并将其用作迭代器的库:
// this is not Scala
def yieldClass(clazz:Class[_]): Iterator[Class[_]] = {
clazz match {
case null =>
case _ =>
sudoYield clazz
for (c <- yieldClass(clazz.getSuperclass)) sudoYield c
for (c <- clazz.getInterfaces; d <- yieldClasss(c)) sudoYield d
}
}
似乎延续允许这样做,但我只是不理解这个shift/reset
概念。延续将最终使其进入主编译器,并且有可能提取出库中的复杂性吗?
尽管Python生成器很酷,但尝试复制它们确实不是Scala中最好的方法。例如,以下代码可以完成所需的工作:
def classStream(clazz: Class[_]): Stream[Class[_]] = clazz match {
case null => Stream.empty
case _ => (
clazz
#:: classStream(clazz.getSuperclass)
#::: clazz.getInterfaces.toStream.flatMap(classStream)
#::: Stream.empty
)
}
在其中,流是延迟生成的,因此它不会处理任何元素,直到被询问为止,您可以通过运行以下命令进行验证:
def classStream(clazz: Class[_]): Stream[Class[_]] = clazz match {
case null => Stream.empty
case _ => (
clazz
#:: { println(clazz.toString+": super"); classStream(clazz.getSuperclass) }
#::: { println(clazz.toString+": interfaces"); clazz.getInterfaces.toStream.flatMap(classStream) }
#::: Stream.empty
)
}
结果可以被转换成Iterator
简单地通过调用.iterator
对所得Stream
:
def classIterator(clazz: Class[_]): Iterator[Class[_]] = classStream(clazz).iterator
使用的foo
定义Stream
将这样呈现:
scala> def foo(i: Int): Stream[Int] = i #:: (if (i > 0) foo(i - 1) else Stream.empty)
foo: (i: Int)Stream[Int]
scala> foo(5) foreach println
5
4
3
2
1
0
另一种选择是将各种迭代器串联起来,注意不要预先计算它们。这是一个示例,其中还包含调试消息以帮助跟踪执行:
def yieldClass(clazz: Class[_]): Iterator[Class[_]] = clazz match {
case null => println("empty"); Iterator.empty
case _ =>
def thisIterator = { println("self of "+clazz); Iterator(clazz) }
def superIterator = { println("super of "+clazz); yieldClass(clazz.getSuperclass) }
def interfacesIterator = { println("interfaces of "+clazz); clazz.getInterfaces.iterator flatMap yieldClass }
thisIterator ++ superIterator ++ interfacesIterator
}
这非常接近您的代码。取而代之的是sudoYield
,我有了定义,然后按需要将它们串联起来。
因此,尽管这是一个无法解决的问题,但我只是认为您在这里树错了树。尝试在Scala中编写Python肯定是徒劳的。在实现相同目标的Scala习惯用法上加倍努力。
问题内容: 我正在努力寻找一种方法,以根据谓词在流的开头跳过某些元素。 像这样: 那相当于Scala 。 问题答案: 这种操作不是s 的预期用例,因为它并入了元素之间的依赖关系。因此,该解决方案可能看起来不太好,因为您必须为谓词引入一个全状态变量: 请注意,与您的示例相比,该条件必须颠倒。 当然,您可以在方法中隐藏令人讨厌的细节: 一个更复杂,但更清洁,可能更有效的方法是深入研究金属,即界面: 可
问题内容: 这是执行字符串替换的两种方法: 如何使用Java做与第一种方法类似的操作? 问题答案: 或更短:
问题内容: 我目前正在玩《暴力Python》一书中的示例。你可以在这里看到我的实现 我现在正在尝试在Go中实现相同的脚本以比较性能,请注意我对Go来说是全新的。打开文件并遍历各行很好,但是我无法弄清楚如何使用“ crypto”库以与Python的crypt.crypt(str_to_hash,salt)相同的方式对字符串进行哈希处理。我想可能是这样的 但是,没有雪茄。任何帮助将不胜感激,因为将Go
问题内容: 我已经找到了以下问题,但我想知道是否有一种更快,更脏的方法来估算不依赖外部库的python解释器当前正在使用多少内存。 我来自PHP,过去经常为此目的使用memory_get_usage()和memory_get_peak_usage(),我希望能找到一个等效的对象。 问题答案: 以下代码为Linux和其他系统提供了一个简单的解决方案,我在我的项目中使用了以下代码: 它返回当前和峰值驻
问题内容: 经过多次尝试优化代码之后,似乎最后的资源就是尝试使用多个内核来运行以下代码。我不确切地知道如何转换/重组我的代码,以便它可以使用多个内核更快地运行。如果能得到指导以实现最终目标,我将不胜感激。最终目标是能够对数组A和B尽可能快地运行此代码,其中每个数组包含大约700,000个元素。这是使用小数组的代码。700k元素数组已被注释掉。 我想做的是模仿一个称为ismember [2]的MAT
问题内容: 我发现compact()和extract()是PHP中的函数,非常方便。compact()在符号表中获取名称列表,并仅使用其值创建哈希表。提取相反。例如, 有没有办法在Python中做同样的事情?我环顾四周,最接近的就是这个线程,似乎对此不满意。 我知道locals(),globals()和vars(),但是如何方便地选择它们的一部分值呢? Python是否有更好的东西可以消除对此的需