如何轻松地从Haskell过渡到Python 3

时间:2015-03-16 17:41:38

标签: python haskell

所以我为我的大学作业写了一些非常漂亮的Haskell代码,并且发现他们不打算为我们的作业支持Haskell。

我收到一封电子邮件,说我应该尝试使用Python,因为它拥有最多的“功能”支持语言。

我已经尝试了一些快速代码转换为python但是我有点困惑这是否真的要看起来很难看。

所以我的Haskell代码是

transitions = map (map (splitOn ",")) $ map (splitOn "->") $ drop 5 $ input'

我的python3代码是

transitions = list(map(lambda x: list(map(lambda y: y.split(","), x)), map(lambda z: z.split("->"), lined_input[5:])))

由于到目前为止我写了大约10行python,我有点希望我错过了处理这类事情的更好方法。

最让我烦恼的是,有时我必须使用x.split,地图必须是map(f,x)。

有没有更好的方法来解决这个问题?

2 个答案:

答案 0 :(得分:5)

我不建议像这样编写Python代码,因为Python使用列表推导和其他技术使这种事情变得更好,但是如果你真的想用函数式编写它,你可以做类似

的事情。
import string
from functools import *
from itertools import *

def take(n, iterable): return islice(iterable, n)
def drop(n, iterable): return islice(iterable, n, None)

def splitOn(sep): return partial(string.split, sep=sep)

transitions = imap(splitOn(','), chain(*imap(splitOn('->'), drop(5, input))))

正如你所知,这是非常混乱的。一个更加pythonic的解决方案可能是

transitions = (c for a in drop(5, input)
                 for b in a.split('->')
                 for c in b.split(','))

这甚至是我认为正则表达式可以接受的情况:

import re

def splitOn(*seps): return partial(re.split, '|'.join(re.escape(sep) for sep in seps))

transitions = imap(splitOn(',', '->'), drop(5, input))

我仍然能够使用功能技术,例如映射,通用接收/删除,部分应用和理解,但是使用更多python功能会更加清晰。我最喜欢的简单案例是简单的生成器理解,但如果你需要更多的分隔符,最后一个很棒。

答案 1 :(得分:4)

  

有没有更好的方法来解决这个问题?

是。不要尝试从Haskell转换代码。使用惯用的Python重写它。

如果您想要一种功能风格,请查看functools。对于涉及列表和其他可迭代对象的任何事情,也要考虑itertools(与切片不同,它是懒惰的)。但请记住,Python是一种多范式编程语言,它采取的立场是使用不同的方法更好地解决不同的问题。