2016-09-20 40 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)]