Add/sum two lists or tuples of uneven length - python

In Python, is there a good way to add/sum (or otherwise combine) two lists of uneven length?
e.g. given some lists:
a = [1,2,3]
b = [1,2,3,4]
produce list c:
c = [2,4,6,4]
where each element is the sum of a and b, taking a missing element as zero?

Yes, you can use itertools.zip_longest():
>>> from itertools import zip_longest
>>> a = [1, 2, 3]
>>> b = [1, 2, 3, 4]
>>> [x + y for x, y in zip_longest(a, b, fillvalue=0)]
[2, 4, 6, 4]

Here's what I landed up using:
[ (ax or 0) + (bx or 0) for (ax, bx) in map(None, a, b) ]
where n or 0 is used to coalesce None to zero, and map(None, a, b) is used as a null-expanding version of zip.
Problems? Better answers?

Another option:
In [1]: a = [1, 2, 3]
In [2]: b = [1, 2, 3, 4]
In [3]: [i+ii if i and ii else i or ii for (i,ii) in map(lambda x,y: (x,y),a,b)]
Out[3]: [2, 4, 6, 4]

Related

Adding elements of lists in Python

How can I add up the elements of two lists in order to make a new list with the updated values. For example:
a = [1,2,3]
b = [3,4,5]
answer = [4,6,8]
I know this is a simple question, but I am new to this thing and cant find an answer anywhere else...
The zip() method would probably be the best way to add up columns, in that order.
a = [1, 3, 5] #your two starting lists
b = [2, 4, 6]
c = [] #the list you would print to
for x,y in zip(a, b): #zip takes 2 iterables; x and y are placeholders for them.
c.append(x + y) # adding on the the list
print c #final result
You may want to learn about list comprehensions, but for this task, it is not required.
>>> a = [1,2,3]
>>> b = [3,4,5]
>>> import operator
>>> map(operator.add, a, b)
[4, 6, 8]
For Python3, you need to use list with the result of map
>>> list(map(operator.add, a, b))
[4, 6, 8]
or just use the usual list comprehension
>>> [sum(x) for x in zip(a,b)]
[4, 6, 8]
>>> a = [1,2,3]
>>> b = [3,4,5]
>>> map(sum, zip(a, b))
[4, 6, 8]
You can use the itertools.izip_longest method to help with this:
def pairwise_sum(a, b):
for x, y in itertools.izip_longest(a, b, fillvalue=0):
yield x + y
You can then use it like this:
a = [1, 2, 3]
b = [3, 4, 5]
answer = list(pairwise_sum(a, b))

Python weave lists

I want to "weave" two numberrows together.
Example:
x = [1,2,3]
y = [4,5,6]
result = [1,4,2,5,3,6]
This is my function, I can't find out why it doesn't work:
def weave(list1,list2):
lijst = []
i = 0
for i <= len(list1):
lijst += [list1[i]]
lijst += [list2[i]]
i + 1
You can use the chain function from itertools module to interleave two lists:
x = [1,2,3]
y = [4,5,6]
from itertools import chain
list(chain.from_iterable(zip(x, y)))
# [1, 4, 2, 5, 3, 6]
Python's for-loops aren't like other languages where you can have a conditional. You need to use a while loop instead or alter your for-loop:
def weave(list1,list2):
lijst = []
i = 0
while i < len(list1):
lijst.append(list1[i])
lijst.append(list2[i])
i += 1
return lijst
I've altered your code in a variety of ways:
Use a while loop if you have a condition you want to loop through
You want the conditional to be less than the length, not less than or equal to. This is because indexing starts at 0, and if you do <=, then it will try to do list1[3] which is out of bounds.
Use list.append to add items to list
You forgot the = in i += 1
Finally, don't forget to return the list!
You could also use zip():
>>> [a for b in zip(x, y) for a in b]
[1, 4, 2, 5, 3, 6]
You can also weave lists by defining the even and odd half-lists of the result list.
x = [1,2,3]
y = [4,5,6]
z = numpy.empty(len(x)+len(y))
z[::2],z[1::2]=x,y
result=z.tolist()
You need to append list item at every iteration so use list.append and in python you don't need to initialise i =0.
try this:-
>>> a = [1,2 ,3]
>>> b = [4, 5, 6]
>>> list(chain.from_iterable(zip(a, b)))
[1, 4, 2, 5, 3, 6]
You can play with this script:
reduce(lambda a, b: a+b, zip([1, 2, 3], [4, 5, 6]), ())
Notes:
zip will make pairs, add will join them;
you can use operator.add instead of lambda;
itertools.izip can be used if lengths of lists are different.
>>> x = [1,2,3]
>>> y = [4,5,6]
>>> z=[]
>>> for i,j in zip(x,y):
... z.extend([i,j])
...
>>> z
[1, 4, 2, 5, 3, 6]
I needed this, but with an arbitrary number of lists of potentially different lengths, which some of the other more elegant answers do not offer. Here is a simple implementation with no dependencies:
def weave_lists(list_of_lists):
max_index = max([len(sublist) for sublist in list_of_lists])
weaved_list = []
for sublist_index in range(max_index):
for sublist in list_of_lists:
if len(sublist) > sublist_index:
weaved_list.append(sublist[sublist_index])
return weaved_list
print(weave_lists([[1,2], [3,4,5], [6,7,8,9]]))
# [1, 3, 6, 2, 4, 7, 5, 8, 9]
x = [1,2,3]
y = [4,5,6]
As mentioned by others (and is the clearest as well as the way I'd do it since it since its the most understandable given the semantics of chain), You can do this by using itertools:
from itertools import chain
list(chain.from_iterable(zip(x, y)))
[1, 4, 2, 5, 3, 6]
However you could also use tuple summing up (concatenation) by:
list(sum(zip(x,y), ()))
[1, 4, 2, 5, 3, 6]

Subtract values in one list from corresponding values in another list

I have two lists:
A = [2, 4, 6, 8, 10]
B = [1, 3, 5, 7, 9]
How do I subtract each value in one list from the corresponding value in the other list and create a list such that:
C = [1, 1, 1, 1, 1]
Thanks.
The easiest way is to use a list comprehension
C = [a - b for a, b in zip(A, B)]
or map():
from operator import sub
C = map(sub, A, B)
Since you appear to be an engineering student, you'll probably want to get familiar with numpy. If you've got it installed, you can do
>>> import numpy as np
>>> a = np.array([2,4,6,8])
>>> b = np.array([1,3,5,7])
>>> c = a-b
>>> print c
[1 1 1 1]
Perhaps this could be usefull.
C = []
for i in range(len(A)):
difference = A[i] - B[i]
C.append(difference)
One liner:
A = [2, 4, 6, 8, 10]
B = [1, 3, 5, 7, 9]
[A[x]-B[x] for x in range(len(B))]
#output
[1, 1, 1, 1, 1]

Sum one number to every element in a list (or array) in Python

Here I go with my basic questions again, but please bear with me.
In Matlab, is fairly simple to add a number to elements in a list:
a = [1,1,1,1,1]
b = a + 1
b then is [2,2,2,2,2]
In python this doesn't seem to work, at least on a list.
Is there a simple fast way to add up a single number to the entire list.
Thanks
if you want to operate with list of numbers it is better to use NumPy arrays:
import numpy
a = [1, 1, 1 ,1, 1]
ar = numpy.array(a)
print ar + 2
gives
[3, 3, 3, 3, 3]
using List Comprehension:
>>> L = [1]*5
>>> [x+1 for x in L]
[2, 2, 2, 2, 2]
>>>
which roughly translates to using a for loop:
>>> newL = []
>>> for x in L:
... newL+=[x+1]
...
>>> newL
[2, 2, 2, 2, 2]
or using map:
>>> map(lambda x:x+1, L)
[2, 2, 2, 2, 2]
>>>
You can also use map:
a = [1, 1, 1, 1, 1]
b = 1
list(map(lambda x: x + b, a))
It gives:
[2, 2, 2, 2, 2]
try this. (I modified the example on the purpose of making it non trivial)
import operator
import numpy as np
n=10
a = list(range(n))
a1 = [1]*len(a)
an = np.array(a)
operator.add is almost more than two times faster
%timeit map(operator.add, a, a1)
than adding with numpy
%timeit an+1
If you don't want list comprehensions:
a = [1,1,1,1,1]
b = []
for i in a:
b.append(i+1)

Get the items not repeated in a list

Take two lists, second with same items than first plus some more:
a = [1,2,3]
b = [1,2,3,4,5]
I want to get a third one, containing only the new items (the ones not repeated):
c = [4,5]
The solution I have right now is:
>>> c = []
>>> for i in ab:
... if ab.count(i) == 1:
... c.append(i)
>>> c
[4, 5]
Is there any other way more pythonic than this?
Thanx folks!
at the very least use a list comprehension:
[x for x in a + b if (a + b).count(x) == 1]
otherwise use the set class:
list(set(a).symmetric_difference(set(b)))
there is also a more compact form:
list(set(a) ^ set(b))
If the order is not important and you can ignore repetitions within a and b, I would simply use sets:
>>> set(b) - set(a)
set([4, 5])
Sets are iterable, so most of the times you do not need to explicitly convert them back to list. If you have to, this does it:
>>> list(set(b) - set(a))
[4, 5]
Items in b that aren't in a, if you need to preserve order or duplicates in b:
>>> a = [1, 2, 3]
>>> b = [1, 2, 3, 4, 4, 5]
>>> a_set = set(a)
>>> [x for x in b if x not in a_set]
[4, 4, 5]
Items in b that aren't in a, not preserving order, and not preserving duplicates in b:
>>> list(set(b) - set(a))
[4, 5]
I'd say go for the set variant, where
set(b) ^ set(a) (set.symmetric_difference())
only applies if you can be certain that a is always a subset of b, but in that case has the advantage of being commutative, ie. you don't have to worry about calculating set(b) ^ set(a) or set(a) ^ set(b); or
set(b) - set(a) (set.difference())
which matches your description more closely, allows a to have extra elements not in b which will not be in the result set, but you have to mind the order (set(a) - set(b) will give you a different result).
Here are some different possibilities with the sets
>>> a = [1, 2, 3, 4, 5, 1, 2]
>>> b = [1, 2, 5, 6]
>>> print list(set(a)^set(b))
[3, 4, 6]
>>> print list(set(a)-set(b))
[3, 4]
>>> print list(set(b)-set(a))
[6]
>>> print list(set(a)-set(b))+list(set(b)-set(a))
[3, 4, 6]
>>>
Another solution using only lists:
a = [1, 2, 3]
b = [1, 2, 3, 4, 5]
c = [n for n in a + b if n not in a or n not in b]
a = [1, 2 ,3]
b = [1, 2, 3, 4, 5]
c=[]
for x in a:
if x not in b:
c.append(x)
print(c)

Categories

Resources