2012-02-09 2 views
3

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

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: argument 2 to map() must support iteration

+0

выход дает объект-генератор, похоже, у вас есть генератор генератора, возможно, вы просто хотите вернуть сумму из add? – dm03514

+0

У вас уже есть ответ, но вы также можете просто сделать 'map (add, a, b)' или '(i + j для i, j в zip (a, b))' –

ответ

6

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

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

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

map(add, a1, a2) 

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

+2

Не могу поверить, что я сделал Не знаю, что карта принимает несколько последовательностей вроде этого - она ​​даже была в учебнике в течение десятилетия. Узнавайте что-то новое каждый день! – DSM

4

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

1

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

from operator import add 

Причина, почему это не работает:

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

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

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

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

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

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

2

I'm trying to make a function using Python that takes in another function and two arrays as parameters and calls the function parameter on each index of each array parameter.

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, взгляните на его doc.
    Несмотря на то, что вам действительно нужно 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.

+0

OP с использованием Python 2 (пример кода включает в себя инструкцию 'print') –

+0

@ChadMiller: Я этого не заметил, спасибо! Я буду менять ссылки :) –

Смежные вопросы