2013-06-03 12 views
0

Есть ли способ привязать функцию (такую ​​же функцию) ко всем элементам массива без прокрутки и привязки один за другим?Связать функции с элементами массива?

Так как

# create function foo from some computation 
foo # some def  

# list 
objects # list of objects 

# attach same foo function to all elements of objects 
# maybe using a decorator? 

# loop through list to execute foo 
for obj in objects: 
    obj.foo() 

Позвольте мне объяснить это подробнее:

Конечно, я могу просто присвоить значение объекта как

obj.attr = value 

или для списка объектов:

for obj in objects: 
    obj.attr = value 

То, что я пытаюсь избежать, это установить значение attr для каждого отдельного объекта, а скорее применить функцию во всем списке/массиве, и каждый элемент выполнит эту функцию.

+0

«Все элементы» весьма сомнительна, учитывая, что «массив» структура Python является список, и может расширяться быть настолько большим, как вам нужно. Вы хотите переписать местоположение с помощью функции или хотите применить функцию к каждому аргументу в списке? – Makoto

+0

Возможный дубликат [Добавление метода к существующему объекту] (http://stackoverflow.com/questions/972/adding-a-method-to-an-existing-object) – GWW

+0

@GWW это не вопрос Я пытаясь спросить, пожалуйста, внимательно прочитайте вопрос. – Derek

ответ

1

Вы можете использовать map. Обычно он используется для создания второго списка и возвращает это значение, но вы можете просто игнорировать его.

map(lambda x: x.foo(), objects) 
+0

карта по существу делает цикл for через список и устанавливает значения, правильно? – Derek

+0

Он просматривает список и создает новый список с возвращаемыми значениями, да. Он не изменяет список, который он вызвал. – Kevin

+0

мой вопрос, вероятно, был путаным, но я стараюсь избегать цикла в массиве, чтобы установить значение для его элементов. – Derek

4

Вы можете сделать функцию, чтобы обернуть его:

def for_each(l, f): 
    for item in l: 
     f(item) 

Тогда для функции foo вы могли бы сделать это:

for_each(objects, foo) 

Для метода foo вы могли бы сделать это:

for_each(objects, lambda item: item.foo()) 

Или это:

from operator import methodcaller 
for_each(objects, methodcaller('foo')) 

В Python 2, вы можете также использовать map:

map(foo, objects) 

Для Python 3, вам придется обернуть, что в list(...). В любом варианте, вы можете использовать списковый:

[foo(item) for item in objects] 

Однако, если вы вызываете функцию только для его побочного эффекта, а не превращая список какой-то образом, я рекомендовал бы против этих двух последних способов, как это против Zen of Python:

Явный лучше, чем неявный.

И, откровенно говоря, еще одна строка для цикла for не так уж много.

+0

+1, я никогда не знал о 'methodcaller' – Blender

+0

не думаю, что это отвечает на мой вопрос, я пытаюсь избежать цикла через массив, чтобы установить значение для его элементов. – Derek

+0

@Derek: Боюсь, я не тогда поймите свой вопрос. Даже с вашим редактированием я смущен. Можете ли вы привести более конкретный пример? – icktoofay

0

использование numpy vectorize! Он будет отлично работать для вас!

from numpy import np 
def fun(x): 
    #do something 
array = np.array(your_list) 
vectfun = np.vectorize(fun) 
answer = vectfun(array) 

Так что теперь ответ будет результирующим массивом, состоящим из всех элементов предыдущего списка с функцией, применяемой к ним!Вот пример:

>>> your_list = [1,2,3,4,5] 
>>> def fun(x): 
...  return x**x 
... 
>>> array = np.array((your_list)) 
>>> vectfun = np.vectorize(fun) 
>>> answer = vectfun(array) 
>>> answer 
array([ 1, 4, 27, 256, 3125]) 
Смежные вопросы