所以我为我的大学作业写了一些非常漂亮的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)。
有没有更好的方法来解决这个问题?
答案 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是一种多范式编程语言,它采取的立场是使用不同的方法更好地解决不同的问题。