在python中展开函数

时间:2016-11-03 21:01:07

标签: python functional-programming functools

我最近开始在python中练习函数式编程。

让我们说我定义了一个获取数字数组并连接它的函数:

In [1]: def fromDigits(digits):
   ...:     return reduce(lambda x,y: 10*x+y,digits,0)
   ...:

In [2]: fromDigits([1,2,3,4,5])
Out[2]: 12345

现在我想实现反向功能:

def toDigits(num):
   return unfold(lambda m,digits: (m/10,digits+[m % 10]) if m>0 else None,  num,  [])

但我无法在unfold functools或标准库中的任何位置找到python的定义。

4 个答案:

答案 0 :(得分:4)

展开不是python函数......这是一个递归解决方案......

def to_digits(x):
    if not x: return []
    return to_digits(x//10) + [x%10]

to_digits(12345)

答案 1 :(得分:0)

出于函数式编程的目的,您可以在python中使用map。 一个例子是: map(lambda a, b: a+b, [1,2,3], [2,3,4]) 这将返回[3, 5, 7]

在您的情况下,您可以这样做:

def toDigits(num):
    return map(int, str(num))

答案 2 :(得分:0)

标准库中没有 unfold 实现。但是,more_itertools 模块中有一个类似的功能。您可以使用 more_itertools.iterate 生成数组。 more_itertools.iterate 可视为 unfold 的非终止版本,因此您需要 itertools.takewhile 来终止迭代器。

from more_itertools import iterate, always_reversible
from itertools import takewhile

def to_digits(num):
  return always_reversible(
    map(
      lambda x: x % 10,
      takewhile(
        lambda x: x > 0,
        iterate(lambda x: x // 10, num)
      )
    )
  )

print(*to_digits(12345))

如果您更喜欢标准库中的函数,您可能需要使用 itertools.accumulate,它可以被认为是更强大的 more_itertools.iterate 版本,因为 itertools.accumulate 需要一个额外的可迭代参数.由于您不需要额外的可迭代对象来生成数字,只需传递 repeat(None) 即可回退到 more_itertools.iterate 行为。

from itertools import takewhile, accumulate, repeat

def to_digits(num):
  return reversed(
    tuple(
      map(
        lambda x: x % 10,
        takewhile(
          lambda x: x > 0,
          accumulate(repeat(None), lambda x, _: x // 10, initial=num)
        )
      )
    )
  )

print(*to_digits(12345))

答案 3 :(得分:-1)

这不使用lambda,它使用列表理解:

def to_digits(x):
    return [int(i) for i in str(x)]

str(x)是一个可复制的字符串版本x,列表推导使其成为一个整数列表(因此int(i))。