Concise vector adding in Python?
Question:
I often do vector addition of Python lists.
Example: I have two lists like these:
a = [0.0, 1.0, 2.0]
b = [3.0, 4.0, 5.0]
I now want to add b to a to get the result a = [3.0, 5.0, 7.0]
.
Usually I end up doing like this:
a[0] += b[0]
a[1] += b[1]
a[2] += b[2]
Is there some efficient, standard way to do this with less typing?
UPDATE: It can be assumed that the lists are of length 3 and contain floats.
Answers:
You could create a function that gets the size of the array, loops through it and creating a return array which it returns.
How about this:
a = [x+y for x,y in zip(a,b)]
[a[x] + b[x] for x in range(0,len(a))]
If you need efficient vector arithmetic, try Numpy.
>>> import numpy
>>> a=numpy.array([0,1,2])
>>> b=numpy.array([3,4,5])
>>> a+b
array([3, 5, 7])
>>>
Or (thanks, Andrew Jaffe),
>>> a += b
>>> a
array([3, 5, 7])
>>>
Or, if you’re willing to use an external library (and fixed-length arrays), use numpy, which has “+=” and related operations for in-place operations.
import numpy as np
a = np.array([0, 1, 2])
b = np.array([3, 4, 5])
a += b
While Numeric is excellent, and list-comprehension solutions OK if you actually wanted to create a new list, I’m surprised nobody suggested the “one obvious way to do it” — a simple for
loop! Best:
for i, bi in enumerate(b): a[i] += bi
Also OK, kinda sorta:
for i in xrange(len(a)): a[i] += b[i]
An improvement (less memory consumption) of the comprehension list
import itertools
a = [x+y for x,y in itertools.izip(a,b)]
Actually if you are not sure that a will be consume then I would even go with generator expression:
(x+y for x,y in itertools.izip(a,b))
If you think Numpy is overkill, this should be really fast, because this code runs in pure C (map()
and __add__()
are both directly implemented in C):
a = [1.0,2.0,3.0]
b = [4.0,5.0,6.0]
c = map(float.__add__, a, b)
Or alternatively, if you don’t know the types in the list:
import operator
c = map(operator.add, a, b)
I don’t think you will find a faster solution than the 3 sums proposed in the question. The advantages of numpy are visible with larger vectors, and also if you need other operators. numpy is specially useful with matrixes, witch are trick to do with python lists.
Still, yet another way to do it 😀
In [1]: a = [1,2,3]
In [2]: b = [2,3,4]
In [3]: map(sum, zip(a,b))
Out[3]: [3, 5, 7]
Edit: you can also use the izip from itertools, a generator version of zip
In [5]: from itertools import izip
In [6]: map(sum, izip(a,b))
Out[6]: [3, 5, 7]
If you’re after concise, try…
vectors = [[0.0, 1.0, 2.0],[3.0, 4.0, 5.0]]
[sum(col) for col in zip(*vectors)]
Though I can’t speak for the performance of this.
list(map(lambda x:x[0]+x[1], zip(a,b)))
For the general case of having a list of lists you could do something like this:
In [2]: import numpy as np
In [3]: a = np.array([[1, 1, 1], [2, 2, 2], [3, 3, 3],[4, 5, 6]])
In [4]: [sum(a[:,i]) for i in xrange(len(a[0]))]
Out[4]: [10, 11, 12]
a = map(lambda x, y: x + y, a, b)
I often do vector addition of Python lists.
Example: I have two lists like these:
a = [0.0, 1.0, 2.0]
b = [3.0, 4.0, 5.0]
I now want to add b to a to get the result a = [3.0, 5.0, 7.0]
.
Usually I end up doing like this:
a[0] += b[0]
a[1] += b[1]
a[2] += b[2]
Is there some efficient, standard way to do this with less typing?
UPDATE: It can be assumed that the lists are of length 3 and contain floats.
You could create a function that gets the size of the array, loops through it and creating a return array which it returns.
How about this:
a = [x+y for x,y in zip(a,b)]
[a[x] + b[x] for x in range(0,len(a))]
If you need efficient vector arithmetic, try Numpy.
>>> import numpy
>>> a=numpy.array([0,1,2])
>>> b=numpy.array([3,4,5])
>>> a+b
array([3, 5, 7])
>>>
Or (thanks, Andrew Jaffe),
>>> a += b
>>> a
array([3, 5, 7])
>>>
Or, if you’re willing to use an external library (and fixed-length arrays), use numpy, which has “+=” and related operations for in-place operations.
import numpy as np
a = np.array([0, 1, 2])
b = np.array([3, 4, 5])
a += b
While Numeric is excellent, and list-comprehension solutions OK if you actually wanted to create a new list, I’m surprised nobody suggested the “one obvious way to do it” — a simple for
loop! Best:
for i, bi in enumerate(b): a[i] += bi
Also OK, kinda sorta:
for i in xrange(len(a)): a[i] += b[i]
An improvement (less memory consumption) of the comprehension list
import itertools
a = [x+y for x,y in itertools.izip(a,b)]
Actually if you are not sure that a will be consume then I would even go with generator expression:
(x+y for x,y in itertools.izip(a,b))
If you think Numpy is overkill, this should be really fast, because this code runs in pure C (map()
and __add__()
are both directly implemented in C):
a = [1.0,2.0,3.0]
b = [4.0,5.0,6.0]
c = map(float.__add__, a, b)
Or alternatively, if you don’t know the types in the list:
import operator
c = map(operator.add, a, b)
I don’t think you will find a faster solution than the 3 sums proposed in the question. The advantages of numpy are visible with larger vectors, and also if you need other operators. numpy is specially useful with matrixes, witch are trick to do with python lists.
Still, yet another way to do it 😀
In [1]: a = [1,2,3]
In [2]: b = [2,3,4]
In [3]: map(sum, zip(a,b))
Out[3]: [3, 5, 7]
Edit: you can also use the izip from itertools, a generator version of zip
In [5]: from itertools import izip
In [6]: map(sum, izip(a,b))
Out[6]: [3, 5, 7]
If you’re after concise, try…
vectors = [[0.0, 1.0, 2.0],[3.0, 4.0, 5.0]]
[sum(col) for col in zip(*vectors)]
Though I can’t speak for the performance of this.
list(map(lambda x:x[0]+x[1], zip(a,b)))
For the general case of having a list of lists you could do something like this:
In [2]: import numpy as np
In [3]: a = np.array([[1, 1, 1], [2, 2, 2], [3, 3, 3],[4, 5, 6]])
In [4]: [sum(a[:,i]) for i in xrange(len(a[0]))]
Out[4]: [10, 11, 12]
a = map(lambda x, y: x + y, a, b)