我将如何在Scala中获得两个列表的平方和? [英] How would I get the sum of squares of two Lists in Scala?

查看:258
本文介绍了我将如何在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转换为类似迭代器的结构,以便在应用诸如mapzip之类的方法以及其他一些方法时不必创建多个中间结构. 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆