pythonic style for functional programming
我对Python没有太多经验。我试图用像Java和JavaScript这样的函数式编写代码。
1 2 3 | var result = getHeroes('Jedi') .map(hero => { hero: hero, movies: getMovies(hero) }) .filter(x => x.movies.contains('A New Hope')); |
我正在尝试用Python做类似的事情,但是我不能得到相同的链接样式。我不得不把它分为两种说法,我不喜欢:
1 2 | 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编写函数式的代码。
这条硬性和快速性的规则有点笨拙,当然也有一些方法可以使用典型的功能性工具,如
1 2 3 4 5 6 | 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)) |
这可以通过列表理解来完成,但可能不太可读。
1 2 | result = [(hero, movies) for hero in get_heros("Jedi") for movies in [get_movies(hero)] if"A New Hope" in movies] |
Generator表达式是一种pythonic方法,但是通过
1 2 | mapper = map(lambda x: (x, get_movies(x)), get_heroes('jedi')) result = filter(lambda x: x[1].contains('A New Hope'), mapper) |
如果您愿意使用第三方库,我建议您使用
1 2 3 4 5 6 7 | 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')) |
如果不需要列表,可以删除组合中的最后一个元素,尽管有状态迭代器/生成器的功能不是很好。
1 2 3 4 5 6 7 8 9 | 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') |
在我看来,他们在Python中以一种功能性的方式(实际上不是pythonic),使用
1 2 3 4 5 6 7 | result = filter ( lambda x: x[1].contains('A New Hope'), map( lambda x: (hero, get_movies(hero)), get_heroes('jedi') ) ) |
肾盂道(功能不太好)将使用发生器表达:
1 | result = ((hero, get_movies(hero)) for hero in get_heroes("jedi") if"A new hope" in get_movies(hero)) |