【问题标题】:Matching the structure of a list?匹配列表的结构?
【发布时间】:2016-09-07 03:49:45
【问题描述】:

例如:

A=[1,[2,3],[4,[5,6]],7]
B=[2,3,4,5,6,7,8]

我怎样才能得到[2,[3,4],[5,[6,7]],8]

【问题讨论】:

  • 请提供有关从输入到输出的所需转换的更多信息。您示例中的输出与输入有何关系?
  • @CraigBurgler 我猜 OP 意味着复制与另一个相同的子列表,因此保持列表的相同“结构”(ure)
  • 返回[2,[3,4],[5,[6,7]],8]
  • 虽然他没有发表任何想法或他想如何做到这一点,但我必须承认这是一个有趣的问题
  • 我的想法是在isinstance(A[i],list) 出现时检查,并保留起始索引和结束索引。然后尝试在数组B 中制定一个类似的数组

标签: python list


【解决方案1】:

你可以使用一个非常简单的递归函数:

def match(struct, source):
    try:
        return [match(i, source) for i in struct]
    except TypeError:
        return next(source)

A=[1,[2,3],[4,[5,6]],7]
B=[2,3,4,5,6,7,8]
match(A, iter(B))
# [2, [3, 4], [5, [6, 7]], 8]

这里是函数的一个版本,可能对某些人来说更容易理解:

def match(struct, source, index=0):
    if isinstance(struct, list):
        r = []
        for item in struct:
            next, index = match(item, source, index)
            r.append(next)
        return r, index
    else:
        return source[index], index + 1

A=[1,[2,3],[4,[5,6]],7]
B=[2,3,4,5,6,7,8]
match(A, B)

基本思想是首先循环输入结构深度,并相应地使用来自源的值。当我们点击一​​个数字时,我们可以简单地从源中获取一个数字。如果我们点击一​​个列表,我们需要将此算法应用于该列表。一路上需要跟踪我们消耗了多少物品。

算法的第一个版本完成了所有这些,但方式略有不同。 iter(B) 创建一个迭代器,用于跟踪 b 中有多少项目已被消耗,并在我调用 next(source) 时提供下一个项目,因此我不必显式跟踪索引。 try/except 检查我是否可以遍历struct。如果可以,则返回一个列表,如果不能,则执行 expect 块并返回 next(source)

【讨论】:

  • 您介意为完全不熟悉 python 的人解释一下确切的算法吗?对你的想法很感兴趣,不幸的是我没有用 python 编程。
  • @Bi Rico:哼。我正在编写基本相同的函数,但检查当前条目的类型以决定何时触底。你的更短,但更不道德。您真的想通过尝试再递归一级并捕获异常来检测递归的底部吗?我想这就是哲学!
  • 捕获异常(鸭子类型)比显式类型检查更 Pythonic
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-14
  • 1970-01-01
  • 2014-12-29
相关资源
最近更新 更多