前言
最近接触函数式编程,做了一个例子,希望能领会其中意义。求笛卡尔积。
做法
通常做法
代码语言:javascript复制arr1 = [1, 3, 5]
arr2 = [2, 4, 6]
def cartesian_product(arr_a, arr_b):
result = []
for x in arr_a:
for y in arr_b:
result.append((x, y))
return result
result = cartesian_product(arr1, arr2)
print(result)
# output:[(1, 2), (1, 4), (1, 6), (3, 2), (3, 4), (3, 6), (5, 2), (5, 4), (5, 6)]
法1
笛卡尔积的本质是把 [1, 1, 1, 3, 3, 3, 5, 5, 5] 和 [2, 4, 6, 2, 4, 6, 2, 4, 6] 上下组合起来。所以得法1如下:
代码语言:javascript复制result = map(lambda l: [l]*len(arr1), arr1)
# output:[[1, 1, 1], [3, 3, 3], [5, 5, 5]]
result = reduce(lambda s,t:s t, result)
# output:[1, 1, 1, 3, 3, 3, 5, 5, 5]
result = map(lambda x,y:(x,y), result, arr2*3)
print(result)
法2
也可以把求值函数先拆分,类似于柯里化,减少参数的个数。具体代码如下:
代码语言:javascript复制def cp_a(a):
def _multi(b):
return map(lambda itemb: (a, itemb), b)
return _multi
fns = map(cp_a,arr1)
# output:[<function _multi at 0x00000000034586D8>, <function _multi at 0x0000000003458748>, <function _multi at 0x00000000034587B8>]
cps = map(lambda x:x(arr2), fns)
# output:[[(1, 2), (1, 4), (1, 6)], [(3, 2), (3, 4), (3, 6)], [(5, 2), (5, 4), (5, 6)]]
cps = reduce(lambda a,b:a b, cps)
print(cps)
# output:[(1, 2), (1, 4), (1, 6), (3, 2), (3, 4), (3, 6), (5, 2), (5, 4), (5, 6)]
法3
事实上对笛卡尔积,python的列表生成天然支持,代码简洁。
代码语言:javascript复制result = [(x,y) for x in arr1 for y in arr2]
print(result)