python笔记:函数式编程求笛卡尔积

2019-11-22 14:35:48 浏览数 (2)

前言

最近接触函数式编程,做了一个例子,希望能领会其中意义。求笛卡尔积。

做法

通常做法

代码语言: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)

0 人点赞