序列是一门高级语言里都会具备的一种数据结构,Scala和Python也不例外。在不同的语言里,序列有着各种不同的别称以及增添了不同的功能,今天只关注Scala和Python基本的内置数据结构。Python要介绍的有两种,分别是列表和元组;Scala里的则是数组,列表和元组。不要被相同的名字糊弄了,Python和Scala的列表和元组虽然同名,但本质上是不一样的。
先来看在Scala里独特的数组:
val array1 = Array(1,2,3)
Scala会根据传入的值自动判定为array1的类型为Array[Int],它的更完整的版本应该是下面的这个
val array2 = new Array[Int](3)
array2(0) = 1
array2(1) = 2
array2(2) = 3
先看第二种稍显复杂的,我们使用了new去初始化了一个长度为3的Int类型的数组实例,而array2(0)=1,这段代码也揭示了一个事实,定义成val的变量,变量本身不可被赋值,但是它指向的对象是可能发生变化的,此时如果在REPL里,输入array2:
scala> array2
res4: Array[Int] = Array(1, 2, 3)
其实无论在Scala和Python,我们都不应该把赋值语句理解为赋值,而是赋与一个指向变量的对象。接着我们在REPL里输入:
scala> array2(0)
res8: Int = 3
这条给数组赋值的语句没有像Python一样,采用[]确定某个位置,而是()。还记得上文提到的吗?i < 5,可以理解为(i).<(5)。同样的,当Scala里使用()将值括起来时,应用(apply)在某个对象时,实际上调用的时.apply方法。
scala> array2.apply(0)
res9: Int = 3
array2(0) = 1这样赋值的时候也是array2.update(0,1)的语法糖。
注: 如果不仅仅限制在内置的数据结构,那么在Python里与Scala的数组很像的是array.array,只不过Python里的array只能装数值类型
import array
arr = array.array('f', (1,2,3))
看完Scala里独特的数组,现在回过头看看列表和元组。Scala的列表是一个拥有相同类型对象的不可变序列,一旦定义了便不可改变,使用方法如下:
scala> val list0 = List(1,2,3)
list0: List[Int] = List(1, 2, 3)
而Python的列表是可以拥有各种类型对象的可变序列(吐槽一下,Python的列表初始化方式之一的列表推导,在Python2的会有内存泄漏的问题,到Python3才修复了),比如我们可以在列表里放入数值和字符串:
list0 = [1,"hello"]
列表除了可以装元素之外,再看看它们的列表有哪些操作,先说列表拼接:
scala> val list1 = List(1,2,3)
list1: List[Int] = List(1, 2, 3)
scala> val list3 = list0 ::: list1
list3: List[Int] = List(1, 2, 3, 1, 2, 3)
Scala使用了:::进行拼接列表,返回了一个新的列表list3,而这个正是Scala一直提倡的不可变的函数式结构,Python的拼接则更加的面向对象,就是原地拼接列表。
>>> list0 += [2]
>>> list0
[1, 'hello', 2]
再看看如何给列表增添元素:
scala> 4 :: list0
res14: List[Int] = List(4, 1, 2, 3)
Scala的list不建议在元素末尾增添元素,而是在列表的头部增加元素,之后再使用reverse方法到过来。空列表的表达方式是Nil。而Python使用append便可以轻易的往后面添加元素,而不像Scala那样花费线性时间,仅仅是常数时间。
>>> list0.append("world")
最后来看看元组: Scala的元组是可以容纳不同类型的元素的容器,使用方法如下:
scala> val tuple0 = (122,"hello")
tuple0: (Int, String) = (122,hello)
scala> tuple0._1
res1: Int = 122
scala> tuple0._2
res2: String = hello
(是不是感觉调用方法很奇怪,用的是._再加序列号进行访问数据,之所以呢?根据《Scala编程》里的解释,是因为Haskell等语言的传统留下来的)。Python的元组则是一个不可变的能容纳各个类型元素的序列,初始化和Scala很相似,使用方式很简单,使用中括号就可以了:
tuple0 = (1,2)
tuple0[0]
1