如何使用map和filter实现这个?

时间:2014-03-24 07:34:25

标签: python

如何使用mapfilter编写语句以获得与此列表推导表达式相同的结果:

[(x,y) for x in range(10) if x%5==0
 for y in range(10) if y%5==1]

结果:

[(0, 1), (0, 6), (5, 1), (5, 6)]

我知道这似乎毫无意义,但我真的很好奇

2 个答案:

答案 0 :(得分:3)

这就是我没有混淆的方式:

sum(map(lambda x: map(lambda y: (x,y), filter(lambda y: y%5==1,range(10))), filter(lambda x: x%5==0,range(10))),[])

执行:

>>> sum(map(lambda x: map(lambda y: (x,y), filter(lambda y: y%5==1,range(10))), filter(lambda x: x%5==0,range(10))),[])
[(0, 1), (0, 6), (5, 1), (5, 6)]

最后一个(也许)讨厌的技巧是使用sum来压缩列表。我得到 [[(0,1),(0,6)],[(5,1),(5,6)]]

答案 1 :(得分:0)

根据对其中一个答案的评论来判断,你想要笛卡儿积的这一部分 - 也就是说,这一点:

[(x,y) for x in range(10) for y in range(10)]

也只使用mapfilter完成。这是不可能的。 map的输出与您输入的迭代数一样多。 filter的输出长度不超过输入的长度。笛卡尔积的长度是输入长度的乘积,没有地图和滤波器的组合可以给你。

要做笛卡尔积产品,需要某种嵌套循环。您可以自己编写,就像在列表推导中一样,或者您可以使用itertools.product

product(range(10), range(10))

之后,您只需要两个过滤器应用程序 - 要直接从listcomp转换为map / filter,您需要为listcomp的每个if部分应用一个过滤器。 ifs附加到每个变量迭代而不是结果,因此您将它们放在产品的每个参数周围 - 这也避免了必须创造性地嵌套它们。最后,我们需要将它传递给list,因为product给出了一个迭代器。

看起来像这样:

list(product(filter(lambda x: (x%5 == 0), range(10)), filter(lambda y: (y % 5 == 1), range(10))))