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

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

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

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

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

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

18 ответов

Решение

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

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

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

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

map(operator.sub, a, b)

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

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

map(int.__sub__, a, b)

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

import numpy as np
a = [2,2,2]
b = [1,1,1]
np.subtract(a,b)

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

Проверьте пакет NumPy для Python.

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

Было предложено много решений.

Если вас интересует скорость, вот обзор различных решений относительно скорости (от самого быстрого до самого медленного).

      import timeit
import operator

a = [2,2,2]
b = [1,1,1]  # we want to obtain c = [2,2,2] - [1,1,1] = [1,1,1

%timeit map(operator.sub, a, b)
176 ns ± 7.18 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

%timeit map(int.__sub__, a, b)
179 ns ± 4.95 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

%timeit map(lambda x,y: x-y, a,b)
189 ns ± 8.1 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

%timeit [a_i - b_i for a_i, b_i in zip(a, b)]
421 ns ± 18.4 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

%timeit [x - b[i] for i, x in enumerate(a)]
452 ns ± 17.2 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each

%timeit [a[i] - b[i] for i in range(len(a))]
530 ns ± 16.7 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

%timeit list(map(lambda x, y: x - y, a, b))
546 ns ± 16.1 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

%timeit np.subtract(a,b)
2.68 µs ± 80.9 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

%timeit list(np.array(a) - np.array(b))
2.82 µs ± 113 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

%timeit np.matrix(a) - np.matrix(b)
12.3 µs ± 437 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

С использованием mapявно самый быстрый. На удивление самый медленный. Получается, что стоимость первого преобразования списков a и b к numpy array - это узкое место, которое перевешивает любой выигрыш в эффективности от векторизации.

      %timeit a = np.array([2,2,2]); b=np.array([1,1,1])
1.55 µs ± 54.9 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

a = np.array([2,2,2])
b = np.array([1,1,1])
%timeit a - b
417 ns ± 12.8 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

Немного другой класс 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)

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

Взято из математики в 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

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

 import operator
 Arr1=[1,2,3,45]
 Arr2=[3,4,56,78]
 print(list(map(operator.sub,Arr1,Arr2)))

Сочетание map а также lambda Функции в Python - хорошее решение для такой проблемы:

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

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

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

Я предлагаю не использовать 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))

использовать цикл for

      a = [3,5,6]
b = [3,7,2]

c = []

for i in range(len(a)):
     c.append(a[i] - b[i])

print(c)

вывод [0, -2, 4]

arr1=[1,2,3]
arr2=[2,1,3]
ls=[arr2-arr1 for arr1,arr2 in zip(arr1,arr2)]
print(ls)
>>[1,-1,0]

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

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

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

Очень просто

      list1=[1,2,3,4,5]
list2=[1,2]
list3=[]
# print(list1-list2)

for element in list1:
    if element not in list2:
       list3.append(element)

print(list3)

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

list(array([1,2,3])-1)
Другие вопросы по тегам