繁体   English   中英

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

[英]Are Python list comprehensions the same thing as map/grep in Perl?

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

例如

(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;

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

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

希望此示例代码演示它们的相等性:

>>> # 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

是的,它们基本相同。

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

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

与上面的第一个例子相同。 但是,列表推导语法在Python中是首选。 我相信Guido被引用说他遗憾地介绍了功能语法。

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

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

[j for i in nested_list for j in i]

使用常规映射和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]

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

例如:

[(x,y)x中x(10)如果x%2 == 0表示x中的y(20)如果x!= y]

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

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM