Restar 2 listas en Python

84

Ahora mismo tengo los valores de vector3 representados como listas. ¿Hay alguna manera de restar 2 de estos valores como vector3, como

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

¿Debería usar tuplas?

Si ninguno de ellos define estos operandos en estos tipos, ¿puedo definirlos en su lugar?

Si no es así, ¿debería crear una nueva clase vector3?

Joan Venge
fuente

Respuestas:

134

Si esto es algo que termina haciendo con frecuencia y con diferentes operaciones, probablemente debería crear una clase para manejar casos como este, o mejor usar alguna biblioteca como Numpy .

De lo contrario, busque las listas de comprensión utilizadas con la función integrada zip :

[a_i - b_i for a_i, b_i in zip(a, b)]
TíoZeiv
fuente
83

Aquí hay una alternativa a la lista de comprensiones. Map itera a través de la (s) lista (s) (los últimos argumentos), haciéndolo de forma simultánea, y pasa sus elementos como argumentos a la función (el primer argumento). Devuelve la lista resultante.

map(operator.sub, a, b)

Este código tiene menos sintaxis (que es más estético para mí), y aparentemente es un 40% más rápido para listas de longitud 5 (ver el comentario de bobince). Aún así, cualquiera de las soluciones funcionará.

Nikhil Chelliah
fuente
Por lo general, veo que se recomiendan listas por comprensión sobre map (), aunque eso puede deberse a que es un código de aspecto más limpio ... no estoy seguro de la diferencia de rendimiento, si es que hay alguna.
David Z
2
El mapa () me sale casi un 40% más rápido en Py2.6 para una resta de cinco elementos. Las comprensiones son más nuevas y más limpias donde evitan una lambda, pero para mapear funciones existentes, el mapa aún puede ser bonito ... especialmente aquí donde puede aprovechar el zip incorporado.
bobince
1
esto también funciona para array.array (aunque el resultado es una lista)
gens
5
se necesita una cláusula de 'operador de importación'; int .__ sub__ hace el truco mejor))
garej
13

Si sus listas son ayb, puede hacer:

map(int.__sub__, a, b)

Pero probablemente no deberías. Nadie sabrá lo que significa.

recursivo
fuente
1
Me encontré con esto yo mismo con flotadores. En cuyo caso map(float.__sub__, a, b)funciona. ¡Gracias por el consejo!
S3DEV
9

Tendría que recomendar NumPy también

No solo es más rápido para hacer matemáticas vectoriales, sino que también tiene un montón de funciones convenientes.

Si quieres algo aún más rápido para vectores 1d, prueba vop

Es similar a MatLab, pero gratis y esas cosas. Aquí tienes un ejemplo de lo que harías

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

Auge.

mikelikespie
fuente
1
np.arraysería una solución más simple
garej
6

Si tiene dos listas llamadas 'a' y 'b', puede hacer: [m - n for m,n in zip(a,b)]

Andy Mikula
fuente
5
import numpy as np
a = [2,2,2]
b = [1,1,1]
np.subtract(a,b)
usuario3503711
fuente
4

Una clase de Vector ligeramente diferente.

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. Lot
fuente
3

Si planea realizar más de una simple línea, sería mejor implementar su propia clase y anular los operadores apropiados según se apliquen a su caso.

Tomado de Matemáticas en 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
fuente
2

Para el que solía codificar en Pycharm, también revive a otros.

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

La combinación de funciones mapy lambdaen Python es una buena solución para este tipo de problema:

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

zip La función es otra buena opción, como lo demuestra @UncleZeiv

BioCoder
fuente
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
fuente
2
Si bien este fragmento de código puede ser la solución, incluir una explicación realmente ayuda a mejorar la calidad de su publicación. Recuerde que está respondiendo a la pregunta para los lectores en el futuro, y es posible que esas personas no conozcan los motivos de su sugerencia de código.
Narendra Jadhav
0

Esta respuesta muestra cómo escribir código pitónico "normal / fácilmente comprensible".

Sugiero no usarlo zipya que no todos lo saben.


Las soluciones utilizan listas por comprensión y funciones integradas comunes.


Alternativa 1 (recomendada):

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

Recomendado ya que solo usa las funciones más básicas en Python


Alternativa 2:

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

Alternativa 3 (como lo menciona BioCoder ):

a = [2, 2, 2]
b = [1, 1, 1]
result = list(map(lambda x, y: x - y, a, b))
Timmy Chan
fuente
¿Por qué el voto negativo? Mi respuesta es única y puede ayudar a otros.
Timmy Chan
-2

Prueba esto:

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