Subtrahieren von 2 Listen in Python

82

Im Moment habe ich vector3-Werte als Listen dargestellt. Gibt es eine Möglichkeit, 2 dieser ähnlichen Vektor-3-Werte zu subtrahieren?

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

Soll ich Tupel verwenden?

Wenn keiner von ihnen diese Operanden für diese Typen definiert, kann ich sie stattdessen definieren?

Wenn nicht, sollte ich eine neue vector3-Klasse erstellen?

Joan Venge
quelle

Antworten:

131

Wenn Sie dies häufig und mit unterschiedlichen Vorgängen tun, sollten Sie wahrscheinlich eine Klasse erstellen, um Fälle wie diesen zu behandeln, oder besser eine Bibliothek wie Numpy verwenden .

Suchen Sie andernfalls nach Listenverständnissen, die mit der integrierten Zip- Funktion verwendet werden:

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

Hier ist eine Alternative zum Listenverständnis. Map durchläuft gleichzeitig die Liste (n) (die letzteren Argumente) und übergibt ihre Elemente als Argumente an die Funktion (das erste Argument). Es gibt die resultierende Liste zurück.

map(operator.sub, a, b)

Dieser Code hat weniger Syntax (was für mich ästhetischer ist) und ist anscheinend 40% schneller für Listen mit einer Länge von 5 (siehe Bobince's Kommentar). Trotzdem wird jede Lösung funktionieren.

Nikhil Chelliah
quelle
Normalerweise werden Listenverständnisse über map () empfohlen, obwohl dies möglicherweise nur daran liegt, dass es sich um saubereren Code handelt. Ich bin mir nicht sicher, ob es Leistungsunterschiede gibt.
David Z
2
Die Karte () erscheint für mich auf Py2.6 fast 40% schneller für eine Subtraktion mit fünf Elementen. Das Verständnis ist neuer und sauberer, wenn ein Lambda vermieden wird, aber für die Zuordnung vorhandener Funktionen kann die Zuordnung immer noch hübsch sein ... insbesondere hier, wo Sie die integrierte Zip-Funktion nutzen können.
Bobince
1
Dies funktioniert auch für array.array (obwohl das Ergebnis eine Liste ist)
gens
5
'Import Operator'-Klausel wird benötigt; int .__ sub__ macht den Trick besser))
garej
13

Wenn Ihre Listen a und b sind, können Sie Folgendes tun:

map(int.__sub__, a, b)

Aber du solltest es wahrscheinlich nicht. Niemand wird wissen, was es bedeutet.

rekursiv
quelle
1
Bin mir selbst mit Schwimmern begegnet. In welchem ​​Fall map(float.__sub__, a, b)funktioniert. Danke für den Tipp!
S3DEV
9

Ich würde empfehlen NumPy auch

Es ist nicht nur schneller für die Vektormathematik, sondern verfügt auch über eine Vielzahl von praktischen Funktionen.

Wenn Sie etwas noch schnelleres für 1d-Vektoren wollen, versuchen Sie es mit vop

Es ist ähnlich wie MatLab, aber kostenlos und so. Hier ist ein Beispiel dafür, was Sie tun würden

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

Boom.

mikelikespie
quelle
1
np.arraywäre eine einfachere Lösung
Garej
6

Wenn Sie zwei Listen mit den Namen "a" und "b" haben, können Sie Folgendes tun: [m - n for m,n in zip(a,b)]

Andy Mikula
quelle
4

Eine etwas andere Vektorklasse.

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)
S.Lott
quelle
4
import numpy as np
a = [2,2,2]
b = [1,1,1]
np.subtract(a,b)
user3503711
quelle
3

Wenn Sie mehr als nur einfache Einzeiler ausführen möchten, ist es besser, eine eigene Klasse zu implementieren und die entsprechenden Operatoren zu überschreiben, die für Ihren Fall gelten.

Entnommen aus der Mathematik 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
codelogic
quelle
2

Für denjenigen, der früher auf Pycharm programmiert hat, werden auch andere wiederbelebt.

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

Die Kombination von mapund lambdaFunktionen in Python ist eine gute Lösung für diese Art von Problem:

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

zip Funktion ist eine weitere gute Wahl, wie @UncleZeiv zeigt

BioCoder
quelle
0
arr1=[1,2,3]
arr2=[2,1,3]
ls=[arr2-arr1 for arr1,arr2 in zip(arr1,arr2)]
print(ls)
>>[1,-1,0]
Ravi Tanwar
quelle
2
Während dieses Code-Snippet die Lösung sein kann, hilft das Hinzufügen einer Erklärung wirklich, die Qualität Ihres Beitrags zu verbessern. Denken Sie daran, dass Sie die Frage in Zukunft für Leser beantworten und diese Personen möglicherweise die Gründe für Ihren Codevorschlag nicht kennen.
Narendra Jadhav
-1

Diese Antwort zeigt, wie man "normalen / leicht verständlichen" Python-Code schreibt.

Ich schlage vor, nicht zu verwenden, zipda nicht wirklich jeder davon weiß.


Die Lösungen verwenden Listenverständnisse und allgemeine integrierte Funktionen.


Alternative 1 (empfohlen):

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

Empfohlen, da nur die grundlegendsten Funktionen in Python verwendet werden


Alternative 2:

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

Alternative 3 (wie von BioCoder erwähnt ):

a = [2, 2, 2]
b = [1, 1, 1]
result = list(map(lambda x, y: x - y, a, b))
Timmy Chan
quelle
Warum das Downvote? Meine Antwort ist einzigartig und kann anderen helfen.
Timmy Chan
-2

Versuche dies:

list(array([1,2,3])-1)
Rostyslav Dzinko
quelle