【问题标题】:Functional programming — for and while loops函数式编程——for和while循环
【发布时间】:2012-06-11 13:26:40
【问题描述】:

我正在尝试用 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()

【问题讨论】:

  • 出于好奇,这个练习的意义何在?
  • 谁需要指出这种事情?他在学习和实验,这太棒了。
  • 我认为你需要lambda i=i: ...。目前它只在你初始化 lambda 时检查是否i&lt;5
  • 这种“函数式编程风格”如何?因为递归??您仍在循环中增加可变变量。 FP 方法将基于对序列结构的归纳......
  • @John,FP 风格不使用循环 :) 它使用 map/filter/reduce :) 并且从不使用全局变量!!!

标签: python functional-programming


【解决方案1】:

FP 风格不使用全局状态(全局变量)并最大限度地减少副作用(例如 IO)。 While-loop 的呼喊看起来像这样:

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)

【讨论】:

  • 在 Python 中很复杂。在 FP 语言中很简单:while p f x | p x = x | otherwise = while p f (f x)
【解决方案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/

【讨论】:

    【解决方案3】:

    可能你需要:

    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()
    

    从功能的角度来看,and 会在左侧字段为 True 时评估右侧字段。您也可以使用or 重写它。顺便说一句,使用全局变量不是一个好习惯。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-08-29
      • 1970-01-01
      • 1970-01-01
      • 2016-01-04
      • 2014-02-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多