
Question:
In Python, a dictionary can be constructed from an iterable collection of tuples:
>>> listOfTuples = zip(range(10), [-x for x in range(10)]) >>> listOfTuples [(0, 0), (1, -1), (2, -2), (3, -3), (4, -4), (5, -5), (6, -6), (7, -7), (8, -8), (9, -9)] >>> theDict = dict(listOfTuples) >>> theDict {0: 0, 1: -1, 2: -2, 3: -3, 4: -4, 5: -5, 6: -6, 7: -7, 8: -8, 9: -9} >>>
Is there an equivalent Scala syntax? I see that you can use a varargs type amount of Tuple2s to construct a map, e.g.
scala> val theMap = Map((0,0),(1,-1)) theMap: scala.collection.immutable.Map[Int,Int] = Map((0,0), (1,-1)) scala> theMap(0) res4: Int = 0 scala> theMap(1) res5: Int = -1 scala> val tuplePairs = List((0,0),(1,-1)) tuplePairs: List[(Int, Int)] = List((0,0), (1,-1)) scala> val mapFromIterable = Map(tuplePairs) <console>:6: error: type mismatch; found : List[(Int, Int)] required: (?, ?) val mapFromIterable = Map(tuplePairs) ^
I could loop through and assign each value manually, but it seems like there must be a better way.
scala> var theMap:scala.collection.mutable.Map[Int,Int] = scala.collection.mutable.Map() theMap: scala.collection.mutable.Map[Int,Int] = Map() scala> tuplePairs.foreach(x => theMap(x._1) = x._2) scala> theMap res13: scala.collection.mutable.Map[Int,Int] = Map((1,-1), (0,0))
Solution:1
Using Scala 2.8.0 final, you can do it like this:
scala> val tuplePairs = List((0,0),(1,-1)) tuplePairs: List[(Int, Int)] = List((0,0), (1,-1)) scala> tuplePairs.toMap res0: scala.collection.immutable.Map[Int,Int] = Map((0,0), (1,-1))
If you're using Scala 2.7.7 you could do something like this, as an alternative to the method you used:
scala> val tuplePairs = List((0,0),(1,-1)) tuplePairs: List[(Int, Int)] = List((0,0), (1,-1)) scala> Map(tuplePairs: _*) res2: scala.collection.immutable.Map[Int,Int] = Map(0 -> 0, 1 -> -1)
but as you can see, in 2.8.0 things have been much improved upon.
Solution:2
While there are some answers that give good advice, here is what I think is closest to the original python code.
// Scala 2.8 val listOfTuples = (0 until 10) zip (for (x <- 0 until 10) yield -x) val theMap = Map(listOfTuples:_*)
Scala 2.7 does not have zip
on Ranges, yet, therefore you have to convert the Ranges to Lists in the first assignment:
// Scala 2.7 val listOfTuples = (0 until 10).toList zip (for (x <- 0 until 10) yield -x).toList val theMap = Map(listOfTuples:_*)
Solution:3
There are several options. First (but not recommmended, IMO), you can convert a List
into a varargs using list:_*
Alternatively, you can use something like the ++ function to add a list of values into a map (which is what Map.apply does anyways)
scala> (Map[Int,Int]()) ++ List((1,2),(3,4)) res4: scala.collection.immutable.Map[Int,Int] = Map(1 -> 2, 3 -> 4) scala> Map(List((1,2),(3,4)):_*) res5: scala.collection.immutable.Map[Int,Int] = Map(1 -> 2, 3 -> 4)
Solution:4
I cannot leave a comment to the accepted answer (not enough reputation yet), but the proposed solution for Scala 2.7 is overly complex:
scala> Map() ++ (tuplePairs map (t => (t._1,t._2))) res2: scala.collection.immutable.Map[Int,Int] = Map(0 -> 0, 1 -> -1)
The "map" isn't doing anything, it's converting a Tuple2 into a Tuple2. This is enough:
scala> Map() ++ tuplePairs res3: scala.collection.immutable.Map[Int,Int] = Map(0 -> 0, 1 -> -1)
In my eyes it would be even better to use Map.empty:
scala> Map.empty ++ tuplePairs res4: scala.collection.immutable.Map[Int,Int] = Map(0 -> 0, 1 -> -1)
Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
EmoticonEmoticon