Віднімання 2 списків у Python


84

Зараз у мене є значення vector3, представлені у вигляді списків. чи є спосіб відняти 2 з них, як значення vector3, як

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

Чи слід використовувати кортежі?

Якщо жоден з них не визначає ці операнди для цих типів, чи можу я визначити його замість цього?

Якщо ні, то чи слід мені створювати новий клас vector3?

Відповіді:


134

Якщо це те, що ви в кінцевому підсумку робите часто і з різними операціями, вам, мабуть, слід створити клас для обробки подібних випадків, або краще скористатися якоюсь бібліотекою, як Numpy .

В іншому випадку шукайте розуміння списків, що використовуються з функцією вбудованого zip :

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

83

Ось альтернатива розуміння списку. Map переглядає список (и) (останні аргументи), роблячи це одночасно, і передає їх елементи як аргументи функції (перший аргумент). Він повертає отриманий список.

map(operator.sub, a, b)

Цей код, оскільки має менше синтаксису (що є для мене більш естетичним), і, мабуть, він швидший на 40% для списків довжиною 5 (див. Коментар bobince). Проте будь-яке рішення буде працювати.


Зазвичай я бачу, як розуміння списків рекомендується над map (), хоча це може бути лише тому, що це чистіший на вигляд код ... не впевнений у різниці в продуктивності, якщо така є.
David Z

2
Карта () виходить для мене майже на 40% швидше на Py2.6 для віднімання п’яти елементів. Розуміння новіші та чистіші там, де вони уникають лямбда-сигналів, але для відображення існуючих функцій карта все одно може бути досить ... особливо тут, де ви можете використовувати вбудований zip.
bobince

1
це також працює для array.array (хоча результат - список)
gens

5
необхідне застереження „імпорт оператора”; int .__ sub__ робить трюк краще))
garej

13

Якщо ваші списки є a та b, ви можете зробити:

map(int.__sub__, a, b)

Але ви, мабуть, не повинні. Ніхто не буде знати, що це означає.


1
Натрапив на це сам із поплавками. У цьому випадку map(float.__sub__, a, b)працює. Дякуємо за підказку!
S3DEV

9

Я б рекомендувати 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

6

Якщо у вас є два списки, які називаються "a" і "b", ви можете зробити: [m - n for m,n in zip(a,b)]



4

Трохи інший векторний клас.

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

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
Хоча цей фрагмент коду може бути рішенням, включаючи пояснення, він дійсно допомагає поліпшити якість вашої публікації. Пам’ятайте, що ви будете відповідати на запитання для читачів у майбутньому, і ці люди можуть не знати причин вашої пропозиції коду.
Нарендра Ядхав,

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))

Чому голос проти? Моя відповідь унікальна і може допомогти іншим.
Тіммі Чан

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.