python 在列表推导和生成器表达式中使用for。这些非常类似于 scala for 表达式:
这是蟒蛇
>>> letters = ['a', 'b', 'c', 'd']
>>> ints = [0, 1, 2, 3]
>>> [l + str(i) for l in letters for i in ints if i % 2 == 0]
['a0', 'a2', 'b0', 'b2', 'c0', 'c2', 'd0', 'd2']
这是斯卡拉
scala> val letters = List('a', 'b', 'c', 'd')
scala> val ints = List(0, 1, 2, 3)
scala> for (l <- letters; i <- ints if i % 2 == 0) yield l.toString + i
res0: List[java.lang.String] = List(a0, a2, b0, b2, c0, c2, d0, d2)
每个构造都可以采用多个生成器/迭代器,应用过滤器表达式并生成组合表达式。在 python 中,(expr for v1 in gen1 if expr1 for v2 in gen2 if expr2) 大致相当于:
for v1 in gen1:
if expr1:
for v2 in gen2:
if expr2:
yield expr
在scala中for (v1 <- gen1 if expr1; v2 <- gen2 if expr2) yield expr大致相当于:
gen1.withFilter(expr1).flatMap(v1 => gen2.withFilter(expr2).map(v2 => expr))
如果您喜欢 python for x in xs 语法,您可能会喜欢 scala for 表达式。
Scala 有一些额外的语法和翻译曲折。语法明智的for 可以与大括号一起使用,以便您可以将语句放在单独的行中。您还可以执行值分配。
val res = for {
i <- 1 to 20; i2 = i*i
j <- 1 to 20; j2 = j*j
k <- 1 to 20; k2 = k*k
if i2 + j2 == k2
} yield (i, j, k)
v1 <- gen1 也确实执行了匹配 case v1 => gen1。如果不匹配,则从迭代中忽略这些元素。
scala> val list = List(Some(1), None, Some(2))
scala> for (Some(i) <- list) yield i
res2: List[Int] = List(1, 2)
我认为for 在语言中占有重要地位。我可以从你正在阅读的书中有一整章 (23) 的事实看出!