Вычитание 2 списков в Python - PullRequest
72 голосов
/ 11 февраля 2009

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

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

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

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

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

Ответы [ 13 ]

115 голосов
/ 11 февраля 2009

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

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

[a_i - b_i for a_i, b_i in zip(a, b)]
78 голосов
/ 11 февраля 2009

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

map(operator.sub, a, b)

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

12 голосов
/ 11 февраля 2009

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

map(int.__sub__, a, b)

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

10 голосов
/ 11 февраля 2009

Я бы рекомендовал 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]]

Boom.

6 голосов
/ 11 февраля 2009

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

4 голосов
/ 11 февраля 2009

Немного другой класс 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 голосов
/ 11 февраля 2009

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

Взято из Математика в 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
2 голосов
/ 09 ноября 2017
import numpy as np
a = [2,2,2]
b = [1,1,1]
np.subtract(a,b)
1 голос
/ 08 февраля 2018

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

 import operator
 Arr1=[1,2,3,45]
 Arr2=[3,4,56,78]
 print(list(map(operator.sub,Arr1,Arr2)))
0 голосов
/ 22 февраля 2019

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

a = [2,2,2]
b = [1,1,1]
map(lambda x,y: x-y, a,b)
Функция

zip - еще один хороший выбор, о чем свидетельствует @ UncleZeiv

...