2016-04-19 5 views
0

Когда я использую NumPy, я могу суммировать два 1D массив просто написав:Как суммировать аргументы списка объектов по-питоновски?

C = A + B 

Если у меня есть список объектов, и все объекты в списке того же класса, и все они имеют три аргумента (r, v и a). Если я хочу вычислить, давайте скажем r = r + v +0.5*a для всех объектов в списке: Как написать это в одной строке, как я бы сделал в numpy зная, что весь мой объект находится в одном списке L?

Нечто подобное я думаю:

L.r += L.v + 0.5*L.a 
+2

Эта (векторизация) - одна из главных причин использования numpy over lists при выполнении артмиты. Насколько я знаю, вы не можете сделать это на родном python, не вызывая для цикла for или list. Из любопытства, почему вы хотите работать за пределами numpy для таких операций? –

+0

Если я использую numpy.asarray в списке объектов, я буду иметь возможность векторизации прямо на аргументы объектов на numpy.array? Он сообщает мне AttributeError: 'numpy.ndarray 'не имеет атрибута' r ' – Phaune

+0

@Phaune, что вам нужно сделать, это создать 3 массива numpy, по одному для каждого свойства, выполнить векторную операцию (что будет намного более эффективно), а затем установить значения в исходном списке объектов. –

ответ

1

Если вы не можете выжить с двумя линиями:

[setattr(item,'r',item.r + item.v + 0.5 * item.a) for item in L] 
+0

Но я действительно рассмотрел комментарий @Adam Hughes, прежде чем делать это. –

0

Если вы можете выжить с двумя линиями попробовать это:

for item in L: 
    item.r += item.v + 0.5 * item.a 
2

Немного непонятно, какой результат вы ищете. Вы ищете список номеров:

[x.r + x.v + .5*x.a for x in L] 

Суммирование этих?

sum([x.r + x.v + .5*x.a for x in L]) 

Или изменить объекты сами?

runningSum=0 
def mod(obj): 
    # How complicated this function is depends on what your trying to accomplish. 
    obj.r = runningSum + obj.r + obj.v + .5*obj.a 
    runningSum = obj.r 
    return obj 

map(mod,L) 
+0

Я не думаю, что в этом вопросе говорится о желаемом выходе, ассер просто хочет реплицировать функциональность numpy. –

1

Пока не формальный ответ, я хотел бы, чтобы забрать свое любопытство и заставить вас представить себе мир возможностей, вытекающих из вашего вопроса. Если по какой-то причине вы не хотите использовать numpy, и вам просто интересно, как сделать сумму всех элементов в списке только в одной строке, вы можете переопределить операцию между списками. Это может быть достигнуто путем определения очень простой класс, как следующему:

class array(): 
    def __init__(self, mylist): 
     self.list = mylist 
     return 
    def __add__(self, other): 
     for i in xrange(len(self.list)): 
      self.list[i] += other.list[i] 
     return array(self.list) 
    def __repr__(self): 
     return "%s" % (self.list) 

Вы можете видеть, что класс экземпляра, используя список питона, а затем я определяю __add__ метод, по существу, указывают, как массив объекты взаимодействуют под символом +. Конечно, здесь есть много возможностей для его улучшения и проверки исключений, но это только для того, чтобы подчеркнуть тот факт, что вы можете определить все, что захотите. Вы можете видеть, что добавление двух объектов массива возвращает новый объект массива, который позволяет нам продолжать добавлять.

Только для вас, чтобы увидеть, как это работает, ниже я пишу очень простой пример:

A = array([1,2,3,4,5]) 
B = array([3,2,4,5,6]) 
C = A+B 

Затем, если вы наберете C в строке, вы увидите

[4, 4, 7, 9, 11] 

который снова это класс массива.

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