python - Scala:递归修改元素/列表的列表

标签 python scala recursion

我希望有人能在 Scala 中为我提供一些基本的代码帮助。我用 Python 编写了一些演示代码。

考虑一个元素列表,其中一个元素可以包含一个整数或其他元素的列表。我想递归地检查这个结构并在保持整体结构的同时修改它。

为了在 python 中表示这一点,我将每个“元素”都变成了一个带有一个键的字典(“i”代表项目)。与该键对应的值是一个 int 或类似字典的列表。因此,

lst = [{'i': 1}, {'i': 2}, {'i': [{'i': 5}, {'i': 6}]}, {'i': 3}]

def recurse(x):
  if isinstance(x, list):
    return [recurse(a) for a in x]
  else:
    if isinstance(x['i'], list):
      return dict(i=[recurse(a) for a in x['i']])
    else:
      return dict(i=(x['i'] + 1))

print "Input:"
for i in lst:
    print i
print "\nResult:\n%s" % recurse(lst)

>>>
Input:
{'i': 1}
{'i': 2}
{'i': [{'i': 5}, {'i': 6}]}
{'i': 3}

Result:    
[{'i': 2}, {'i': 3}, {'i': [{'i': 6}, {'i': 7}]}, {'i': 4}]

我知道这种做事的方式有点奇怪,但我提供的数据的结构是这样的。我认为我的问题是 python 允许您从同一个函数返回不同的类型,而我不认为 Scala 可以。

另请注意,Scala 元素表示为 Elem(4) 或 Elem(List(Elem(3)...,因此我假设模式匹配可以在某种程度上发挥作用。

最佳答案

我宁愿不称它为列表的列表,因为它并没有说明这些列表包含什么。该结构是一棵树,更准确地说是一棵多叶树,其中只有叶子中有数据。那将是:

sealed trait Tree[+A]
case class Node[+A](children: Tree[A]*) extends Tree[A]
case class Leaf[+A](value: A) extends Tree[A]

然后添加一个方法映射以对树中的每个值应用一个函数

sealed trait Tree[+A] {
  def map[B](f: A => B): Tree[B]
}
case class Node[+A](children: Tree[A]*) extends Tree[A] {
  def map[B](f : A => B) = Node(children.map(_.map(f)): _*)
}
case class Leaf[+A](value: A) extends Tree[A] {
  def map[B](f: A => B) = Leaf(f(value))
}

那么你的输入是:

val input = Node(Leaf(1), Leaf(2), Node(Leaf(5), Leaf(6)), Leaf(3))

如果你调用 input.map(_ + 1) 你会得到你的输出

由于可变参数 Tree[A]*,结果显示有些难看。您可以通过在 Node 中添加 override def toString = "Node("+ children.mkString(", ") + ")"

进行改进

您可能只喜欢一个地方的方法,要么在类之外,要么直接在 Tree 中。这里作为 Tree 中的一个方法

def map[B](f: A => B): Tree[B] = this match {
  case Node(children @ _*) => Node(children.map(_.map(f)): _*)
  case Leaf(v) => Leaf(f(v))
}

以 Python 中的非类型化方式工作不是很像 scala,但可以做到。

def recurse(x: Any) : Any = x match {
  case list : List[_] => list.map(recurse(_))
  case value : Int => value + 1
}

(将值直接放在列表中。您的带有键“i”的 map (字典)使其复杂化并强制接受编译器警告,因为我们将不得不强制进行无法检查的强制转换,即 map 接受字符串作为键:案例映射:Map[String, _])


在我看来,使用 case Elem(content: Any) 与直接将值放入 List 相比并没有提供额外的安全性,而且更加冗长,而且调用它也没有安全性和清晰度一棵树和可区分的节点和叶子,而不会明显变得更简洁。

关于python - Scala:递归修改元素/列表的列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6395119/

相关文章:

scala - 如何使用平面图分解数据集?

scala - Spark 1.6 : java. lang.IllegalArgumentException : spark. sql.execution.id 已经设置

python - 为什么我的递归冒泡排序不起作用?

python - 在 ubuntu 14.04 上使用 python 版本安装 MORSE 模拟器的问题

python - 如何等待具有非空内容的元素出现?

python - 查找行的匹配值并分别提取,无需指定匹配值(key)

scala - 为什么这个案例类可以容纳比它声明的更多的参数?

java - 响应时间随着 Java 中并发性的增加而增加

recursion - 具有匹配模式错误的F#递归函数

python - 使用 Xpath 提取给定 anchor 标记文本的 href