Python, как сделать функцию, которая принимает функцию в качестве аргумента вместе с двумя массивами? - PullRequest
3 голосов
/ 09 февраля 2012

В целях обучения я пытаюсь создать функцию, использующую Python, которая принимает другую функцию и два массива в качестве параметров и вызывает параметр функции для каждого индекса каждого параметра массива.Так что это должно вызвать add для a1 [0] & a2 [0], a1 [1] & a2 [1] и т. Д. Но все, что я получаю, это объект генератора.Что не так?

def add(a,b):
    yield a + b


def generator(add,a1,a2):
    for i in range(len(a1)):
        yield add(a1[i],a2[i])


g = generator(add,a1,a2)

print g.next()

Я также пытался заменить то, что у меня есть для доходности выше, на

yield map(add,a1[i],a2[i])

Но это работает еще меньше.Я получаю это:

TypeError: аргумент 2 для map () должен поддерживать итерацию

Ответы [ 4 ]

6 голосов
/ 09 февраля 2012

Ваше определение add() по меньшей мере странно (я склоняюсь над двумя словами, называя это "неправильно"). Вы должны return результат, а не yield это:

def add(a, b):
    return a + b

Теперь ваш generator() будет работать, хотя

map(add, a1, a2)

- это более простой и быстрый способ сделать (почти) то же самое. (Если вам нужен итератор, а не список, используйте itertools.imap() вместо map().)

4 голосов
/ 09 февраля 2012

Вы получаете генератор, потому что ваш add является генератором. Это должно быть просто return a + b.

2 голосов
/ 09 февраля 2012

Я пытаюсь сделать функцией , используя Python , который принимает другую функцию и два массива в качестве параметров и вызывает параметр функции для каждого индекса каждого параметра массива .

def my_function(func, array_1, array_2):
    for e_1,e_2 in zip(array_1, array_2):
        yield func(e_1,e_2)

Пример:

def add(a, b):
    return a + b

for result in my_function(add, [1, 2, 3], [9, 8, 7]):
    print(result)

напечатает:

10
10
10

Теперь пара замечаний:

  • Функцию add можно найти в модуле operator.
  • Вы видите, что я использовал zip, взгляните на его документ .
    Хотя на самом деле вам нужно izip() выражение генератора в zip(), которое в основном возвращает не список, а итератор для каждого значения.
  • my_function почти как map(), единственное отличие состоит в том, что my_function является генератором, а map() дает вам список. Еще раз, stdlib дает вам версию генератора map в модуле itertools: imap()

Например, my_fuction аналогично imap:

from operator import add
from itertools import imap

for result in imap(add, [1, 2, 3], [9, 8, 7]):
    print(result)

#10
#10
#10

Я, очевидно, предполагаю, что функция add была просто быстрым примером, в противном случае проверьте встроенную sum.

1 голос
/ 09 февраля 2012

Как уже говорили другие, вы определяете add неправильно, и оно должно return вместо yield.Также вы можете импортировать его:

from operator import add

Причина, по которой это не работает:

yield map(add, a1[i], a2[i])

Это потому, что map работает со списками / итерациями, а не с отдельными значениями.Если add были определены правильно, это может сработать:

yield map(add, [a[i]], [a2[i]])

Но на самом деле вы не должны этого делать, потому что это сложнее, чем должно быть без веской причины (как показывает ответ Свена Марнаха, ваш генераторфункция - это просто попытка реализовать map, поэтому она не должна использовать map, даже если это учебное упражнение).Наконец, если цель состоит в том, чтобы создать функцию, которая принимает функцию в качестве параметра, я бы не назвал параметр «добавить»;в противном случае, какой смысл вообще это делать?

def generator(f, a1, a2):
    for x, y in zip(a1, a2):
        yield f(x, y)

Говоря об этом, взгляните на zip.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...