Python列表理解与Perl中的map / grep是一回事吗?

时间:2009-09-13 21:41:59

标签: python perl list

我在使用Python中的列表理解语法时遇到了一些麻烦,所以我开始考虑如何在Perl中实现相同的功能,我更熟悉它。我意识到基本示例(取自this page)都可以使用mapgrep在Perl中完成。

E.g。

(python)                            (perl)                  
S = [x**2 for x in range(10)]       @S = map { $_**2 } ( 0..9 );
V = [2**i for i in range(13)]       @V = map { 2**$_ } ( 0..12 );
M = [x for x in S if x % 2 == 0]    @M = grep { $_ % 2 == 0 } @S;

“列表理解”只是“地图和/或过滤列表”的一个奇特术语,还是有更多内容?

6 个答案:

答案 0 :(得分:14)

你是对的:列表理解基本上只是地图和过滤器的语法糖(来自函数式编程世界的术语)。

希望这个示例代码能够证明它们的平等性:

>>> # Python 2
>>> [x**2 for x in range(10)] == map(lambda x: x**2, range(10))
True
>>> [2**i for i in range(13)] == map(lambda x: 2**x, range(13))
True
>>> S = [x**2 for x in range(10)]
>>> [x for x in S if x % 2 == 0] == filter(lambda x: x % 2 == 0, S)
True

请注意,这仅在Python 2.X中有效,正如SilentGhost在注释中指出的那样。为了使它与Python 3兼容,你必须在list构造函数中包含对map或filter的调用,因为map和filter已经更新以返回迭代器,而不是列表。

>>> # Python 3
>>> [x**2 for x in range(10)] == list(map(lambda x: x**2, range(10)))
True
>>> [2**i for i in range(13)] == list(map(lambda x: 2**x, range(13)))
True
>>> S = [x**2 for x in range(10)]
>>> [x for x in S if x % 2 == 0] == list(filter(lambda x: x % 2 == 0, S))
True

答案 1 :(得分:3)

是的,它们基本相同。

实际上Python也有一个map函数:

S = map(lambda x: x**2, range(10))

与上面的第一个示例相同。但是,列表推导语法在Python中是首选。我相信Guido被引用说他后悔引入功能语法。

然而,它真正有趣的地方在于列表推导的下一个演变,即生成器。这些允许您返回迭代器 - 而不是一次处理整个列表,它只进行一次迭代然后返回,这样您就不必同时将整个列表保存在内存中。非常强大。

答案 2 :(得分:2)

它们是用于映射和过滤序列的“pythonic”版本,但它们允许执行其他一些操作,例如展平(固定级别)嵌套列表,例如:

[j for i in nested_list for j in i]

使用常规 map 和lambda表达式无法做到的另一件事是在结构上分解迭代值,例如:

[(x%y)*z for x,y,z in list_with_triplets_of_ints]

当然有一些解决方法,如:

aux = lambda x,y,z: (x%y)*z
map(lambda t: aux(*t), list_with_triplets_of_ints)

但是当您需要应用的转换已经定义时,通常使用地图会更简单,例如:

map(int, list_of_str_values)

而不是

[int(i) for i in list_of_str_values]

答案 3 :(得分:2)

列表理解也使事情变得平淡:

例如:

[(x,y)for x in xrange(10)if x%2 == 0 for y in xrange(20)if x!= y]

如果你在这里使用嵌套地图,你也必须使用concat(汇总列表)。

答案 4 :(得分:0)

列表推导比地图或过滤器更强大,因为它们允许您抽象地使用列表。

当您的地图进一步嵌套更多地图和过滤器调用时,使用它们也会更方便。

答案 5 :(得分:0)

是。 Python语法的强大之处在于,相同的语法(在圆形而不是方括号内)也用于定义生成器,生成器按需生成值序列。

相关问题