Odejmowanie 2 list w Pythonie


84

W tej chwili mam wartości vector3 reprezentowane jako listy. czy istnieje sposób na odjęcie 2 z tych wartości, takich jak vector3, na przykład

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

Czy powinienem używać krotek?

Jeśli żaden z nich nie definiuje tych operandów na tych typach, czy mogę je zamiast tego zdefiniować?

Jeśli nie, czy powinienem utworzyć nową klasę vector3?

Odpowiedzi:


134

Jeśli jest to coś, co często robisz, i przy różnych operacjach, prawdopodobnie powinieneś utworzyć klasę do obsługi takich przypadków lub lepiej użyć jakiejś biblioteki, takiej jak Numpy .

W przeciwnym razie, poszukaj listowych używany z zamkiem wbudowanej funkcji:

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

83

Oto alternatywa dla list składanych. Map iteruje listę (y) (ostatnie argumenty), robiąc to jednocześnie, i przekazuje ich elementy jako argumenty do funkcji (pierwszy argument). Zwraca wynikową listę.

map(operator.sub, a, b)

Ten kod, ponieważ ma mniejszą składnię (co jest dla mnie bardziej estetyczne) i najwyraźniej jest o 40% szybszy dla list o długości 5 (patrz komentarz bobince'a). Mimo to oba rozwiązania będą działać.


Zwykle widzę, że listy składane są ponownie polecane przez map (), chociaż może to być spowodowane tylko tym, że jest to bardziej przejrzysty kod ... nie jestem pewien, czy różnica w wydajności istnieje.
David Z

2
Mapa () wychodzi prawie 40% szybciej na Py2.6 przy odejmowaniu pięciu elementów. Zrozumienia są nowsze i bardziej przejrzyste tam, gdzie unikają lambda, ale do mapowania istniejących funkcji mapa może być nadal ładna ... szczególnie tutaj, gdzie można wykorzystać wbudowany zip.
bobince

1
działa to również dla array.array (chociaż wynikiem jest lista)
gens

5
wymagana jest klauzula „operator importu”; int .__ sub__ radzi sobie lepiej))
garej

13

Jeśli Twoje listy to a i b, możesz:

map(int.__sub__, a, b)

Ale prawdopodobnie nie powinieneś. Nikt nie będzie wiedział, co to znaczy.


1
Sam wpadłem na to z pływakami. W takim przypadku map(float.__sub__, a, b)działa. Dzięki za wskazówkę!
S3DEV

9

Musiałbym polecam NumPy także

Jest nie tylko szybszy do wykonywania obliczeń wektorowych, ale ma również mnóstwo wygodnych funkcji.

Jeśli chcesz czegoś jeszcze szybszego dla wektorów 1d, wypróbuj vop

Jest podobny do MatLab, ale darmowy i takie tam. Oto przykład tego, co byś zrobił

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

Bum.


1
np.arraybyłoby prostszym rozwiązaniem
garej

6

Jeśli masz dwie listy o nazwach „a” i „b”, możesz: [m - n for m,n in zip(a,b)]



4

Nieco inna klasa 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

Jeśli planujesz wykonywać więcej niż zwykłe wkładki typu one, byłoby lepiej zaimplementować własną klasę i zastąpić odpowiednie operatory, które mają zastosowanie w twoim przypadku.

Zaczerpnięte z 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

2

Dla tego, który programował na Pycharmie, ożywia także innych.

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

1

Połączenie funkcji mapi lambdaw Pythonie jest dobrym rozwiązaniem tego rodzaju problemu:

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

zip funkcja jest kolejnym dobrym wyborem, jak pokazuje @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
Chociaż ten fragment kodu może być rozwiązaniem, dołączenie wyjaśnienia naprawdę pomaga poprawić jakość Twojego posta. Pamiętaj, że odpowiadasz na pytanie do czytelników w przyszłości, a osoby te mogą nie znać powodów, dla których zaproponowałeś kod.
Narendra Jadhav

0

Ta odpowiedź pokazuje, jak napisać „normalny / łatwo zrozumiały” kod Pythona.

Proponuję nie używać, zipponieważ tak naprawdę nie wszyscy o tym wiedzą.


Rozwiązania używają list składanych i typowych funkcji wbudowanych.


Alternatywa 1 (zalecana):

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

Zalecane, ponieważ używa tylko najbardziej podstawowych funkcji w Pythonie


Alternatywa 2:

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

Alternatywa 3 (jak wspomniano przez BioCoder ):

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

Dlaczego głos przeciw? Moja odpowiedź jest wyjątkowa i może być pomocna dla innych.
Timmy Chan,

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.