我将如何在Scala中获得两个列表的平方和? [英] How would I get the sum of squares of two Lists in Scala?
问题描述
如果我有两个列表
val first = List(1, 2, 3)
val second = List(4, 5, 6)
我将如何获得以下信息?
How would I obtain the following?
(1-4)^2 + (2-5)^2 + (3-6)^2
推荐答案
zip,映射和求和:
zip, map and sum:
first.view.zip(second).map(t => t._1 - t._2).map(x => x*x).sum
- zip 将两个列表的元素组合成一个元组
- view 用于延迟计算列表,以免在两个地图调用之间建立结构
- zip combine elements of the two list into a tuple
- view is used to have the list computed lazily to not build a structure between the two map calls
(将reduceLeft
替换为sum
的编辑)
看到评论后,我觉得我不得不回过头来解释观点.基本上,视图将Traversable
转换为类似迭代器的结构,以便在应用诸如map
,zip
之类的方法以及其他一些方法时不必创建多个中间结构. GenIteratableViewLike 的类型成员赋予了一种感觉哪些操作有特殊处理.因此,通常,如果按顺序应用了一堆map,filter,drop,takeWhile,则可以使用view获得一些性能.经验法则是尽早应用view
以最大程度地减少创建多少中间List
,如有必要,最后使用force
返回到List
(或您使用的任何集合).因此,丹尼尔的建议.
After seeing the comments, I feel I had to come back and explain about views. Basically a view turns a Traversable
into an iterator like structure so that multiple intermediate structures don't have to be created when apply methods like map
, zip
and a few others. The type members of GenIteratableViewLike gives a sense of what operations have special processing. So typically if you have a bunch of map, filter, drop, takeWhile applied in sequence, you can use view to gain some performance. The rule of thumb is to apply view
early to minimize how many intermediate List
are created and if necessary use force
at the end to go back to List
(or whatever collection you're using). Thus Daniel's suggestion.
关于性能的事情是,在实践中,如果这很重要,则必须进行现实检查.以下是一些数字(越小越好):
The thing about performance is that in practice if that's important you sort of have to do a reality check. Here are some numbers (lower is better):
no view List(62, 62, 62, 62, 63) sum: 311
view before zip List(32, 31, 15, 16, 31) sum: 125
view after zip List(31, 46, 46, 31, 31) sum: 185
iterator List(16, 16, 16, 16, 15) sum: 79
zipped List(62, 47, 62, 46, 47) sum: 264
代码在这里:
import testing.Benchmark
def lots[T](n: Int, f: => T): T = if (n > 0) { f; lots(n - 1, f) } else f
def bench(n: Int, id: String)(block: => Unit) {
val times = (new testing.Benchmark {
def run() = lots(10000, block)
}).runBenchmark(n)
println(id + " " + times + " sum: " + times.sum)
}
val first = List(1, 2, 3)
val second = List(4, 5, 6)
bench(5, "no view") { first.zip(second).map(t => t._1 - t._2).map(x => x*x).sum }
bench(5, "view before zip") { first.view.zip(second).map(t => t._1 - t._2).map(x => x*x).sum }
bench(5, "view after zip") { first.zip(second).view.map(t => t._1 - t._2).map(x => x*x).sum }
bench(5, "iterator") { first.iterator.zip(second.iterator).map(t => t._1 - t._2).map(x => x*x).sum }
bench(5, "zipped") { (first, second).zipped.map((a,b) => a - b).map(x => x*x).sum }
这篇关于我将如何在Scala中获得两个列表的平方和?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!