函数式编程——for和while循环

6

我正在尝试使用Python函数式编程风格来编写forwhile循环。

我认为for循环可以正常工作,但是while循环不行,它会无限运行。

# for loop
lst = [1, 2, 3]
def fun(e):
   return e
print map(fun, lst)


# while loop
i = 1
def whileloop():
    global i
    print i
    i = i+1
while_FP = lambda: ((i < 5) and whileloop()) or while_FP()
while_FP()

2
好奇问一句,这个练习的目的是什么? - NPE
21
谁需要这种事情的要点?他正在学习和尝试,这很棒。 - SomeKittens
1
我认为你需要 lambda i=i: ...。目前,当你初始化 lambda 时,它只检查 i<5 - Junuxx
8
这是“函数式编程风格”吗?因为使用了递归?但你仍在循环中增加可变变量。函数式编程的方法是基于对序列结构的归纳…… - Don Stewart
3
@John,FP 风格不使用循环 :) 它使用 map/filter/reduce :) 并且从不使用全局变量!!! - Aleksei astynax Pirogov
显示剩余3条评论
3个回答

9

FP风格不使用全局状态(全局变量),并尽量减少副作用(例如IO)。while循环应该像这样:

fp_while = lambda pred, fun, acc: (lambda val: fp_while(pred, fun, val) if pred(val) else val)(fun(acc))

print fp_while(lambda x: x < 5, lambda x: x + 1, 1)

如果您需要副作用:

def add_and_print(x):
   print x
   return x + 1

fp_while(lambda x: x < 5, add_and_print, 1)

5
在Python中,这个问题比较复杂。但在函数式编程语言中,这个问题很简单:while p f x | p x = x | otherwise = while p f (f x) - Don Stewart

2

如果你有太多的迭代,使用像@aleksei-astynax-pirogov所回答的递归会导致递归错误。相反,你可以将状态的副作用隐藏在一个函数内部。

def fp_while(pred, fun, acc):
    v = acc
    while(pred(v)):
        v = fun(v)
    return v 

使用示例:

fp_while(lambda x: x < 5, lambda x: x + 1, 1)
print(fp_while(lambda x: x < 5, lambda x: x + 1, 1))
# outputs 5

使用生成器的方法

以下生成器方法可以让您在每次迭代时存储状态

def fp_while_generator(pred, fun, acc):
    v = acc
    while(pred(v)):
        yield v
        v = fun(v)
    yield v # remove this if you do not want the last value that fails the check

使用示例:

my_while_generator = fp_while_generator(lambda x: x < 5, lambda x: x + 1, 1)
print([i for i in my_while_generator])
# outputs [1,2,3,4,5]

更多有关生成器的信息 https://realpython.com/introduction-to-python-generators/


-1

可能你需要:

i = 1
def whileloop():
    global i
    print i
    i = i+1
    return True

while_FP = lambda: ((i < 5) and whileloop()) and while_FP()
while_FP()

从功能角度来看,如果左侧为True,则评估右侧字段。您也可以使用or进行重写。顺便说一下,使用全局变量不是一个好的实践。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接