如何在不使用内置地图或星图的情况下编写类似星图的函数?

How to write a starmap-like function without using the builtin map or starmap?

这是任务:

Make a function my_map_k that as arguments takes a function f and k lists L1,...,Lk, for an arbitrary k ≥ 1, and returns the list [f(L1[0],...,Lk[0]),...,f(L1[n-1],...,Lk[n-1])], where n is the length of the shortest Li list.

Hint. Use Python's * notation to handle an arbitrary number of lists as arguments.

Example:

my_map_k(lambda x, y, z: x*y*z, [3, 2, 5], [2, 7, 9], [1, 2])

should return [6, 28].

这就是我的进展,但我被卡住了。

def my_map_k(f, *L):
    n = len(min(*L, key=len))
    x=0
    while x < n:
        return [f(*L[x],) for x in L]

my_map_k(lambda x, y, z: x*y*z, [3, 2, 5], [2, 7, 9], [1, 2])

问题是,我不能只说有 3 个列表,因为可能还有更多。此外,我看不出如何从所有三个列表中取出第一个元素。

这是一个不使用内置地图函数的解决方案:

from itertools import starmap

def my_map_k(f, *L):
    return list(starmap(f, zip(*L)))

我想通了:

def my_map_k(f, *L):
    z = zip(*L)
    l = list(z)
    return ([f(*x) for x in l])

my_map_k(lambda x, y, z: x*y*z, [3, 2, 5], [2, 7, 9], [1, 2])

您可以使用 zip() to take the nth element from each list in turn, and a list comprehension 来调用提供的函数,每组参数如此生成:

def my_map_k(f, *lists):
    return [f(*args) for args in zip(*lists)]

这是实际操作:

>>> my_map_k(lambda x, y, z: x*y*z, [3, 2, 5], [2, 7, 9], [1, 2])
[6, 28]

没有辅助函数的解决方案:

from operator import add

def my_map_k(f, *L):
    ind = 0
    while True:
        try:
            yield f(*[l[ind] for l in L])
        except IndexError:
            break
        else:
            ind += 1

result = my_map_k(add, range(5), range(5))
print(list(result))
# [0, 2, 4, 6, 8]