【发布时间】:2009-10-09 13:39:13
【问题描述】:
查看 Python 和 Javascript 中的推导式,到目前为止,我看不到一些我认为在 Haskell 等语言推导式中最强大的主要功能。
他们是否允许多个生成器之类的东西?还是它们只是一个基本的地图过滤器形式?
如果他们不允许多个生成器,我觉得他们很失望 - 为什么这些东西被遗漏了?
【问题讨论】:
标签: javascript python haskell list-comprehension
查看 Python 和 Javascript 中的推导式,到目前为止,我看不到一些我认为在 Haskell 等语言推导式中最强大的主要功能。
他们是否允许多个生成器之类的东西?还是它们只是一个基本的地图过滤器形式?
如果他们不允许多个生成器,我觉得他们很失望 - 为什么这些东西被遗漏了?
【问题讨论】:
标签: javascript python haskell list-comprehension
Python 允许多个生成器:
>>> [(x,y,x*y) for x in range(1,5) for y in range(1,5)]
[(1, 1, 1), (1, 2, 2), (1, 3, 3), (1, 4, 4),
(2, 1, 2), (2, 2, 4), (2, 3, 6), (2, 4, 8),
(3, 1, 3), (3, 2, 6), (3, 3, 9), (3, 4, 12),
(4, 1, 4), (4, 2, 8), (4, 3, 12), (4, 4, 16)]
还有限制:
>>> [(x,y,x*y) for x in range(1,5) for y in range(1,5) if x*y > 8]
[(3, 3, 9), (3, 4, 12), (4, 3, 12), (4, 4, 16)]
更新:Javascript的语法类似(在firefox上使用javascript shell的结果):
var nums = [1, 2, 3, 21, 22, 30];
var s = eval('[[i,j] for each (i in nums) for each (j in [3,4]) if (i%2 == 0)]');
s.toSource();
[[2, 3], [2, 4], [22, 3], [22, 4], [30, 3], [30, 4]]
(出于某种原因,在 javascript shell 中评估有关上下文内容的某些内容需要 eval 间接以使列表推导起作用。<script> 标记内的 Javascript 当然不需要这样做)
【讨论】:
assert isinstance(ob, type)
是的,Python list comprehension 中可以有多个迭代:
>>> [(x,y) for x in range(2) for y in range(3)]
[(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2)]
【讨论】:
同时添加一个 if 语句...
>>> [(x,y) for x in range(5) for y in range(6) if x % 3 == 0 and y % 2 == 0]
[(0, 0), (0, 2), (0, 4), (3, 0), (3, 2), (3, 4)]
【讨论】:
Haskell 中的 Comprehensions 在很大程度上是非常强大的,因为 Haskell 是函数式的,所以对它们来说非常有意义。 Python 没有功能,所以它的意义不大。
您可以在 Python 中使用推导式做很多复杂的事情,但很快就会变得难以阅读,从而违背了整个目的(意味着您应该以其他方式来做)。
然而,正如这里所指出的,python 确实允许在推导中使用多个生成器。
【讨论】:
yield 或__next__ 创建自己的生成器。