【问题标题】:Python deep zipPython 深拉链
【发布时间】:2012-09-27 21:43:43
【问题描述】:

我正在尝试编写一个类似 zip 的函数。我不擅长解释我的意思,所以我只会显示我正在尝试做的“代码”。

a = [1,2,3,[4,5]]
b = a[:]
zip(a, b) == [(1,1), (2,2), (3,3), ([4,5],[4,5])]
myzip(a, b) == [(1,1), (2,2), (3,3), [(4,4), (5,5)]]

我非常坚持这一点,这甚至都不好笑。我正在尝试使用递归 lambda 以简单的函数式方式编写它,以使我的代码更漂亮。我想要这样的 myzip,因为我想将它的输出与我编写的另一个函数一起使用,该函数将函数映射到树

def tree_map(func, tree):
    return map(lambda x: func(x) if not isinstance(x, list) else tree_map(func, x), 
               tree)

我一直在尝试用 zip 做类似的事情,但我似乎无法理解它。有人对我如何编写 myzip 有任何想法吗?

编辑:看看tree_map!是不是很漂亮!至少我是这么认为的,但我的母语是 Scheme :P 而且,我希望 myzip 尽可能深入。基本上,我希望 myzip 保留我通过它的树的结构。另外,myzip 只会处理形状相同的树。

【问题讨论】:

  • “我正在尝试使用递归 lambda 以简单的函数式方式编写它,以使我的代码更漂亮。”这就像.. 好吧,不,我不会想出一些喜剧明喻。但是使用 lambdas 递归不太可能让你的代码更漂亮。
  • 只有 2 级可以,还是必须无限?
  • 你有没有想过检查itertools?有一些 Python 伪代码展示了可以激发你灵感的逻辑......

标签: python functional-programming


【解决方案1】:

我认为以下应该可行:

import collections

def myzip(*args):
    if all(isinstance(arg, collections.Iterable) for arg in args):
        return [myzip(*vals) for vals in zip(*args)]
    return args

结果:

>>> a = [1,2,3,[4,[5,6]]]
>>> b = [1,2,3,[4,[5,6]]]
>>> myzip(a, b)
[(1, 1), (2, 2), (3, 3), [(4, 4), [(5, 5), (6, 6)]]]

请注意,我在类型检查中使用 collections.Iterable 而不是 list,因此行为更像是带有元组和其他可迭代对象的 zip()

【讨论】:

  • 太棒了!!!!!!太棒了!!!我想,如果不是几天的话,我需要几个小时才能想到这一点。谢谢!
  • +1。您可能想要坚持 all 的 args 是列表,而不仅仅是第一个,因此您可以做一些合理的事情(如扁平 zip)而不是例外......除非当然不应该这样做是有效的,在这种情况下例外是完美的。此外,您可能想使用collections.Iterable 而不是列表(因此它可以深度压缩元组等)。或者甚至将整个事情写成一个可迭代的而不是一个列表。但这很有效,而且很简单。
  • @abarnert - 感谢您的建议,现在myzip([[1]], [1]) 返回[([1], 1)] 而不是引发异常。
猜你喜欢
  • 2018-04-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-23
  • 2014-09-04
  • 2018-11-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多