gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-28 19:33:37 27 4
gpt4 key购买 nike

我希望有人能在 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/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com