問題描述
使用 map/reduce 在列表中添加一對數字的差異 (Adding difference of pair of numbers in list using map/reduce)
我正在使用 python 練習函數式編程概念的練習。我遇到了這個問題。我已經嘗試了很多,但找不到使用函數式編程結構(如 map/reduce、閉包)的解決方案。
問題:給定一個數字列表
list = [10, 9, 8, 7, 6, 5, 4, 3]
求差異之和每對使用 Map/Reduce 或任何函數式編程概念,例如
[[10 ‑9] + [8 ‑ 7] + [6 ‑5] + [4 ‑ 3]] = 4
對我來說,棘手的部分是使用 map/reduce/recursion/closure 隔離對
參考解法
方法 1:
The recursive relationship you are looking for is
f([4, 3, 2, 1]) = 4 ‑ 3 + 2 ‑ 1 = 4 ‑ (3 ‑ 2 + 1) = 4 ‑ f([3, 2, 1])
方法 2:
One of the mantras followed by many functional programmers is the following:
- Data should be organized into data structures that mirror the processing you want to perform on it
Applying this to your question, you're running into a simple problem: the list data structure doesn't encode in any way the relationship between the pairs that you want to operate on. So map
/reduce
operations, since they work on the structure of lists, don't have any natural visibility into the pairs! This means you're "swimming against the current" of these operations, so to speak.
So the first step should be to organize the data as a list or stream of pairs:
pairs = [(10, 9), (8, 7), (6, 5), (4, 3)]
Now after you've done this, it's trivial to use map
to take the difference of the elements of each pair. So basically I'm telling you to split the problem into two easier subproblems:
- Write a function that groups lists into pairs like that.
- Use
map
to compute the difference of each pair.
And the hint I'll give is that neither map
nor reduce
is particularly useful for step #1.
方法 3:
using itertools.starmap:
l = [10, 9, 8, 7, 6, 5, 4, 3]
from operator import sub
from itertools import starmap
print(sum(starmap(sub, zip(*[iter(l)] * 2))))
4
Or just a lambda:
print(sum(map(lambda x: sub(*x), zip(*[iter(l)] * 2))))
Or range and itemgetter:
from operator import itemgetter as itgt
print(sum(itgt(*range(0, len(l), 2))(l)) ‑ sum(itgt(*range(1, len(l), 2))(l)))
方法 4:
Another try may be isolating pairs‑You may need to sort the list beforehand
>>>import operator
>>>l=[10, 9, 8, 7, 6, 5, 4, 3]
>>>d= zip(l,l[1:])
>>>w=[d[i] for i in range(0,len(d),2)]#isolate pairs i.e. [(10, 9), (8, 7), (6, 5), (4, 3)]
>>>reduce(operator.add,[reduce(operator.sub,i) for i in w])
>>>4
方法 5:
You can do it in simple way.
l = [10, 9, 8, 7, 6, 5, 4, 3]
reduce(lambda x, y : y ‑ x, l) * ‑1
(by s007、Karolis Juodelė、Luis Casillas、Padraic Cunningham、SIslam、Kaushal Kumar Singh)