2009-02-10 4 views
53

Прямо сейчас у меня есть значения vector3, представленные в виде списков. существует способ вычитания 2 таких значений вектора3, какВычитание 2 списков в Python

[2,2,2] - [1,1,1] = [1,1,1] 

Должен ли я использовать кортежи?

Если ни один из них не определяет эти операнды для этих типов, могу ли я определить его вместо этого?

Если нет, должен ли я создать новый класс vector3?

ответ

96

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

В противном случае, искать list comprehensions использоваться с zip встроено функции:

[a_i - b_i for a_i, b_i in zip(a, b)] 
+43

'[i-j для i, j in zip (a, b)]' более читаемо и не заменяет a и b элементами из a и b. –

4

Если у вас есть два списка под названием «а» и «б», вы можете сделать: [m - n for m,n in zip(a,b)]

8

Отъезд NumPy пакет для питона.

+1

Почему бы не сказать 'use numpy array', чтобы спасти людей от изучения всего пакета numpy? –

3

Если вы планируете выполнять больше простых прошивок, было бы лучше реализовать свой собственный класс и переопределить соответствующие операторы, как они применяются к вашему делу.

Взятые из Mathematics in Python:

class Vector: 

    def __init__(self, data): 
    self.data = data 

    def __repr__(self): 
    return repr(self.data) 

    def __add__(self, other): 
    data = [] 
    for j in range(len(self.data)): 
     data.append(self.data[j] + other.data[j]) 
    return Vector(data) 

x = Vector([1, 2, 3])  
print x + x 
9

Если ваши списки а и б, вы можете сделать:

map(int.__sub__, a, b) 

Но вы, вероятно, не следует. Никто не узнает, что это значит.

+0

это круто ответ. – garej

66

Предлагаемая альтернатива перечню понятий. Карта выполняет итерацию по списку (последним аргументам), делая это симулятивно и передает свои элементы в качестве аргументов функции (первый аргумент). Он возвращает результирующий список.

map(operator.sub, a, b) 

Этот код, потому что имеет меньше синтаксис (что более эстетичным для меня), и, видимо, это 40% быстрее для списков длины 5 (см комментарий bobince в). Тем не менее, любое решение будет работать.

+0

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

+2

Карта() выходит на 40% быстрее для меня на Py2.6 для пятиэлементного вычитания. Познания новее и чище, где они избегают лямбда, но для сопоставления существующих функций карта все еще может быть довольно ... особенно здесь, где вы можете использовать встроенный почтовый индекс. – bobince

+1

Это более чем отличный ответ, я очень ценю это! – user69453

4

Немного другой класс Vector.

class Vector(object): 
    def __init__(self, *data): 
     self.data = data 
    def __repr__(self): 
     return repr(self.data) 
    def __add__(self, other): 
     return tuple((a+b for a,b in zip(self.data, other.data))) 
    def __sub__(self, other): 
     return tuple((a-b for a,b in zip(self.data, other.data))) 

Vector(1, 2, 3) - Vector(1, 1, 1) 
+0

Отличный ответ, это очень полезно. –

10

Я бы рекомендовать NumPy а

Не только это быстрее делать векторную математику, но он также имеет массу удобных функций.

Если вы хотите что-то даже быстрее 1d векторов, попробуйте vop

Это похоже на MatLab, но бесплатно и прочее. Вот пример того, что вы сделали бы

from numpy import matrix 
a = matrix((2,2,2)) 
b = matrix((1,1,1)) 
ret = a - b 
print ret 
>> [[1 1 1]] 

Бум.

+1

'np.array' будет более простым решением – garej

-1

Попробуйте это:

list(array([1,2,3])-1) 
+0

это работает только для numpy, не так ли? – SilentGhost

0

Если вы хотите результат в списке:

list(numpy.array(list1)-numpy.array(list2)) 

, если не удалить список.

0

Для тех, кто использовал код в Pycharm, он также оживляет и другие.

import operator 
Arr1=[1,2,3,45] 
Arr2=[3,4,56,78] 
print(list(map(operator.sub,Arr1,Arr2))) 
Смежные вопросы