[英]pythonic style for functional programming
我对 Python 没有太多经验。 我正在尝试以 Java 和 JavaScript 习惯的功能风格进行编码
var result = getHeroes('Jedi')
.map(hero => { hero: hero, movies: getMovies(hero) })
.filter(x => x.movies.contains('A New Hope'));
我正在尝试在 Python 中做类似的事情,但我无法获得相同的链接样式。 我不得不把它分解成两个我不喜欢的陈述:
tmp = ((hero, get_movies(hero)) for hero in get_heroes('jedi'))
result = ((hero, movies) for (hero, movies) in tmp if movies.contains('A New Hope')
我有两个问题:
谢谢你。
作为喜欢函数式编程的人, 不要在Python中使用函数式编写 。
这个坚硬而快速的规则有点笨拙,并且有一些方法可以使用典型的功能工具(例如map
, filter
和reduce
)来做你正在尝试做的事情(在Python中称为functools.reduce
),但它很可能是你的功能代码看起来会比罪恶更加丑陋,在这种情况下,没有理由更喜欢它而不是命令式和漂亮的东西。
result = []
for hero in get_heros("Jedi"):
movies = get_movies(hero)
for movie in movies:
if "A New Hope" in movies:
result.append((hero, movies))
这可以通过列表理解来完成,但可能性较差。
result = [(hero, movies) for hero in get_heros("Jedi")
for movies in [get_movies(hero)] if "A New Hope" in movies]
IMO他们在python(实际上不是pythonic)的功能样式中使用map
和filter
:
result = filter (
lambda x: x[1].contains('A New Hope'),
map(
lambda x: (hero, get_movies(hero)),
get_heroes('jedi')
)
)
pythonic方式(不是非常实用)将使用生成器表达式:
result = ((hero, get_movies(hero)) for hero in get_heroes("jedi") if "A new hope" in get_movies(hero))
如果您愿意使用第三方库,我建议fn.py
使用其语法糖作为成分
from fn import F
result = (
F(map, lambda hero: dict(hero=hero, movies=getMovies(hero))) >>
(filter, lambda x: 'A New Hope' in x['movies']) >>
list
)(getHeroes('Jedi'))
如果您不想要列表,则可以删除合成中的最后一个元素,尽管有状态迭代器/生成器功能不是很强。 F
-objects包装callables并使部分应用和组合更容易。 一系列F
-expressions是一种可以多次使用的新功能。 这更接近于传统意义上的函数式编程:程序是组合:
program = (
F(map, lambda hero: dict(hero=hero, movies=getMovies(hero))) >>
(filter, lambda x: 'A New Hope' in x['movies']) >>
list
)
result = program(getHeroes('Jedi'))
# or even
result = (F(getHeroes) >> program)('Jedi')
我很惊讶没有人使用pytoolz的pipe
提出以下建议:
from toolz import pipe
result = pipe(
get_heroes("Jedi"),
lambda hs: [{"hero": h, "movies": get_movies(h)} for h in hs],
lambda xs: [x for x in xs if "A New Hope" in x["movies"]],
)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.