2016-09-20 76 views
0

如何使用映射和过滤器编写以下代码的等效代码?使用映射和过滤器而不是for循环?

res = [] 
for x in range(5): 
    if x % 2 == 0: 
     for y in range(5): 
      if y % 2 == 1: 
       res.append((x, y)) 

这是预期的结果:

[(0, 1), (0, 3), (2, 1), (2, 3), (4, 1), (4, 3)] 

这是我写的代码,但它似乎并没有工作:

list(map((lambda x,y: (x,y)), filter((lambda x: x%2 == 0), range(5)), filter((lambda y: y%2 != 0), range(5)))) 
+0

比较你有两种方法,请记住[可读性计数](https://www.python.org/dev/peps/pep-0020/)。 – Phillip

+0

谢谢。我会记住这一点。我只是想更好地理解地图和过滤器。 :) – Taiwosam

回答

3

你可以写为(在Python 2.x):

xs = filter(lambda x: x % 2 == 0, range(5)) 
ys = filter(lambda y: y % 2 == 1, range(5)) 
res = [(x, y) for x in xs for y in ys] 

这也使用list comprehension

在Python 3.X:

xs = list(filter(lambda x: x % 2 == 0, range(5))) 
ys = list(filter(lambda y: y % 2 == 1, range(5))) 
res = [(x, y) for x in xs for y in ys] 
+0

这在3.X中给出了[(0,1),(0,3)]'。过滤器对象需要包装在list()中。它在我做到这一点时起作用。非常感谢您的回答! (x)= list(filter(lambda x:x%2 == 0,range(5))) ys = list(filter(lambda:y%2 == 1,range(5))) res = [(x,y)for xs for ys in ys]' – Taiwosam

+0

@Taiwosam:谢谢您的评论。我已经更新了答案,以便为其他人明确。 –

2

你甚至都不需要映射和过滤器,你可以做整个事情列表中的理解

[(x,y) for x in range(5) for y in range(5) if not x%2 and y%2] 
1

您需要使用product方法从itertools,它产生输入迭代的笛卡尔乘积。

x_arr = [x for x in range(5) if x % 2 == 0] 
y_arr = [y for y in range(5) if x % 2 == 1] 
from itertools import product 
final_arr = product(x_arr, y_arr) 

输出将[(0, 1), (0, 3), (2, 1), (2, 3), (4, 1), (4, 3)]

1

替代方案,您可以利用的事实,即奇数或偶数可以通过使用第三step说法range捕获:

>>> sorted((x,y) for y in range(1,5,2) for x in range(0,5,2)) 
[(0, 1), (0, 3), (2, 1), (2, 3), (4, 1), (4, 3)]