1

This is the task:

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].

This is how far I've gotten, but I'm stuck.

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])

The problem is, I cannot just say that there are 3 lists, because there could be more. Furthermore I cannot see how to take the first element out of all three lists.

Zero Piraeus
  • 56,143
  • 27
  • 150
  • 160
NicklasS
  • 35
  • 6

4 Answers4

3

You can use zip() to take the nth element from each list in turn, and a list comprehension to call the supplied function with each group of arguments so generated:

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

Here it is in action:

>>> my_map_k(lambda x, y, z: x*y*z, [3, 2, 5], [2, 7, 9], [1, 2])
[6, 28]
Zero Piraeus
  • 56,143
  • 27
  • 150
  • 160
1

I figured it out:

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])
Zero Piraeus
  • 56,143
  • 27
  • 150
  • 160
NicklasS
  • 35
  • 6
0

Here's a solution which does not use builtin map function:

from itertools import starmap

def my_map_k(f, *L):
    return list(starmap(f, zip(*L)))
panda-34
  • 4,089
  • 20
  • 25
  • I don't think I'm alloved to use starmap neither. I think the point is to make a recursive function or something like that. – NicklasS Mar 08 '19 at 12:59
0

Solution with no helper functions:

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]
Mykola Zotko
  • 15,583
  • 3
  • 71
  • 73