Вычитание 2 списков в Python

86

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

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

Стоит ли использовать кортежи?

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

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

Джоан Венге
источник

Ответы:

135

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

В противном случае поищите списки, используемые встроенной функцией zip :

[a_i - b_i for a_i, b_i in zip(a, b)]
Дядя Зеив
источник
83

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

import operator
map(operator.sub, a, b)

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

Никхил Челлия
источник
Обычно я вижу, что понимание списков рекомендуется вместо map (), хотя это может быть просто потому, что это более чистый код ... не уверен в разнице в производительности, если таковая имеется.
David Z
2
Map () у меня получается почти на 40% быстрее на Py2.6 для пятиэлементного вычитания. Понимания новее и чище там, где они избегают лямбда, но для отображения существующих функций карта все еще может быть красивой ... особенно здесь, где вы можете использовать встроенный zip.
bob с
1
это также работает для array.array (хотя результат представляет собой список)
gens
6
необходимо условие «оператор импорта»; int .__ sub__ работает лучше))
garej
13

Если у вас есть списки a и b, вы можете:

map(int.__sub__, a, b)

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

рекурсивный
источник
1
Наткнулся на это сам с поплавками. В этом случае map(float.__sub__, a, b)работает. Спасибо за совет!
S3DEV
9

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

Он не только быстрее выполняет векторные математические вычисления, но и имеет массу удобных функций.

Если вы хотите что-то еще быстрее для одномерных векторов, попробуйте 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 09
6

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

Энди Микула
источник
5
import numpy as np
a = [2,2,2]
b = [1,1,1]
np.subtract(a,b)
user3503711
источник
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)
С.Лотт
источник
3

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

Взято из математики в 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
codelogic
источник
2

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

 import operator
 Arr1=[1,2,3,45]
 Arr2=[3,4,56,78]
 print(list(map(operator.sub,Arr1,Arr2)))
Сахил Нагпал
источник
1

Сочетание mapи lambdaфункция в Python является хорошим решением для такого рода проблемы:

a = [2,2,2]
b = [1,1,1]
map(lambda x,y: x-y, a,b)

zip функция - еще один хороший выбор, как продемонстрировал @UncleZeiv

Биокодер
источник
0
arr1=[1,2,3]
arr2=[2,1,3]
ls=[arr2-arr1 for arr1,arr2 in zip(arr1,arr2)]
print(ls)
>>[1,-1,0]
Рави Танвар
источник
2
Хотя этот фрагмент кода может быть решением, включение объяснения действительно помогает улучшить качество вашего сообщения. Помните, что вы отвечаете на вопрос читателей в будущем, и эти люди могут не знать причин вашего предложения кода.
Narendra Jadhav
0

Этот ответ показывает, как писать "нормальный / простой для понимания" питонический код.

Я предлагаю не использовать, так zipкак не все об этом знают.


В решениях используются списки и стандартные встроенные функции.


Альтернатива 1 (рекомендуется):

a = [2, 2, 2]
b = [1, 1, 1]
result = [a[i] - b[i] for i in range(len(a))]

Рекомендуется, так как он использует только самые основные функции Python


Альтернатива 2:

a = [2, 2, 2]
b = [1, 1, 1]
result = [x - b[i] for i, x in enumerate(a)]

Альтернатива 3 (как упомянуто BioCoder ):

a = [2, 2, 2]
b = [1, 1, 1]
result = list(map(lambda x, y: x - y, a, b))
Тимми Чан
источник
Почему голос против? Мой ответ уникален и может помочь другим.
Тимми Чан
-2

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

list(array([1,2,3])-1)
Ростислав Дзинько
источник