Как написать starmap-подобную функцию без использования встроенной карты или starmap? - PullRequest
1 голос
/ 08 марта 2019

Это задача:

Сделать функцию my_map_k, которая в качестве аргумента принимает функцию f и k перечисляет L 1 , ..., L k , для произвольного k ≥ 1, и возвращает список [F (L 1 [0], ..., L к [0]), ..., F (L 1 [п-1 ], ..., L k [n-1])], где n - длина кратчайшего списка L i .

Совет. Используйте нотацию Python * для обработки произвольного числа списков в качестве аргументов.

Пример:

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

должен вернуть [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 списка, потому что их может быть больше. Более того, я не понимаю, как вычеркнуть первый элемент из всех трех списков.

Ответы [ 4 ]

3 голосов
/ 08 марта 2019

Вы можете использовать zip(), чтобы взять n -й элемент из каждого списка по очереди, а понимание списка длявызовите предоставленную функцию с каждой сгенерированной группой аргументов:

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]
1 голос
/ 08 марта 2019

Я понял это:

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])
0 голосов
/ 08 марта 2019

Решение без вспомогательных функций:

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]
0 голосов
/ 08 марта 2019

Вот решение, которое не использует встроенную функцию карты:

from itertools import starmap

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