我最近开始在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
的定义。
答案 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)
)。