Multiplying a list by a nested list - python

I am trying to multiply a list by a nested list.
For example if we have
a=[1,2,3]
b=[[2,4,6],[3,5,7]]
I am trying to multiply each element of 'list b' by elements of 'list a'
I am trying to achieve something along these lines
product=[[2,8,18],[3,10,21]]
Here is what I tried so far
product=[[w*c for c in v] for w, v in zip(a, b)]
and result I got is
[[-4.0, -8.0, -12.0], [0.0, 0.0, 0.0]]
which is clearly not what I expected
I am not allowed to use numpy by the way.

I would have a inner zip, because a outer zip will zip with a and b, with each pairs of list with each element in a, so it will fail.
print([[y*z for y,z in zip(a,x)] for x in b])
Output:
[[2, 8, 18], [3, 10, 21]]

a=[1,2,3]
b=[[2,4,6],[3,5,7]]
for idxa, val in enumerate(a):
for idxb, sublist in enumerate(b):
b[idxb][idxa] = sublist[idxa] * val
Results in b equal to [[2, 8, 18], [3, 10, 21]] and may be easier to reason about if just starting out with Python rather than dealing with list comprehension and zip or other functional programming calls.

You can use zip in combination with list comprehension:
product = [[i*j for i,j in zip(a,k)] for k in b]

Related

Converting float to integers in a specific sublist

Let's make this short.
I have a list of lists, for example
a = [[1.0, 2.0], [6, 8]]
What I would like to do, is to convert all values of the first sublist into integers, so the array will be
a = [[1, 2], [6, 8]]
Can you please tell me how to do it? I struggled with map already, yet I can't seem to find the correct usage. Thanks in advance.
You can use a nested list comprehension:
[[int(y) for y in x] for x in a]
Or with map:
[list(map(int, x)) for x in a]
You can use list comprehension for the first list (that needs transformation), and add the second list (which you don't need to change).
print([[int(aa) for aa in a[0]], a[1]])
Out[46]: [[1, 2], [6, 8]]
Unlike the other solutions, this does not change the 2nd part of the list in any way.
If you only want to change the first delivery list, an option
[a for a in map(lambda n, x: list(x if n else int(x) for x in a[n]), (0, 1), a)]
You can assign it to a variable and then print to the screen.
b = [a for a in map(lambda n, x: list(x if n else int(x) for x in a[n]), (0, 1), a)]
print(b)
remembering that it will only transform the values ​​in the left list

How to add integers together in two matrices using the zip() function in Python

I cannot figure out how to add integers together in two matrices using the zip() function. Here is what I have:
matrix_a = [[3,6],[4,5]]
matrix_b = [[5,8],[6,7]]
I need to print out (using zip()):
[[8,14],[10,12]]
The following list comprehension will do the trick:
>>> [[x + y for x, y in zip(a, b)] for a, b in zip(matrix_a, matrix_b)]
[[8, 14], [10, 2]]
If you want the version that uses loops:
result = []
for a, b in zip(matrix_a, matrix_b):
current_list = []
for x, y in zip(a, b):
current_list.append(x + y)
result.append(current_list)
>>> result
[[8, 14], [10, 2]]
However, I definitely like more the comprehension version it is easier to read.

Using list comprehension to keep items not in second list

I am trying to use list comprehension to remove a number of items from a list by just keeping those not specified.
For example if I have 2 lists a = [1,3,5,7,10] and b = [2,4] I want to keep all items from a that are not at an index corresponding to a number in b.
Now, I tried to use y = [a[x] for x not in b] but this produces a SyntaxError.
y = [a[x] for x in b] works fine and keeps just exact the elements that i want removed.
So how do I achieve this? And on a side note, is this a good way to do it or should I use del?
You can use enumerate() and look up indexes in b:
>>> a = [1, 3, 5, 7, 10]
>>> b = [2, 4]
>>> [item for index, item in enumerate(a) if index not in b]
[1, 3, 7]
Note that to improve the lookup time, better have the b as a set instead of a list. Lookups into sets are O(1) on average while in a list - O(n) where n is the length of the list.
Guess you're looking for somthing like :
[ x for x in a if a.index(x) not in b ]
Or, using filter:
filter(lambda x : a.index(x) not in b , a)
Try this it will work
[j for i,j in enumerate(a) if i not in b ]
after this:
y = [a[x] for x in b]
just add:
for x in y:
a.remove(x)
then you end up with a stripped down list in a

Calling functions on lists

I have a spectra of wavelengths as a list and some number of other lists I use in a formula (using tmm.tmm_core). Is there something more efficient than iterating through the wavelength if I'm just basically doing the same thing for all wavelengths?
Example
def go(n, thk, theta):
#do stuff
return(something)
wv = [1, 2, 3, 4]
a_vec = [3, 7, 3, 9]
b_vec = [6, 5, 9, 3]
c_vec = [0, 1, 8, 9]
theta = 0
th = [10, 1, 10]
final = []
for i in range(len(wv)):
n = [a[i], b[i], c[i]]
answer = go(n, th, theta)
final.append(answer)
in reality there are maybe 5000-10000 rows. It just seems to lag a bit when I press go and I assume it's because of the iteration. Pretty new to optimizing so I haven't used any benchmarking tools or anything.
I think you're looking for the map function in Python!
>>> list1 = [1,2,3,4]
>>> list2 = [5,6,7,8]
>>> map(lambda x,y: x+y, list1, list2)
[6, 8, 10, 12]
it takes in a function (in the above case, an anonymous lambda function), one or more lists and returns another list. At each iteration within the function, both lists are iterated and the result is added to the new list. You don't need to limit yourself to the expressive power of a lambda statement; you can also use globally defined functions as in the case below:
>>> def go(a,b,c):
... return a+b+c
...
>>> map(go, list1,list2, range(9,13))
[15, 18, 21, 24]
You can put all of your lists within a custom list like C_list and use map to create a new list all_len contain the length of all lists then use a list comprehension to create the list final :
all_len=map(len,C_list)
final =[[go([a[i], b[i], c[i]], th, theta) for i in range(li)] for li in all_len]
Also if the length of a and b and c are equal you can use zip function to zip then and refuse of multiple indexing :
all_len=map(len,C_list)
z=zip(a,b,c)
final =[[go(z[i], th, theta) for i in range(li)] for li in all_len]
If you have to perform an operation on every item in the list, then you're gonna have to go through every item in the list. However, you could gain speed through the use of list comprehensions: List Comprehensions

Finding the sum of matching components in two lists

I have two lists:
A = [1, 2, 3, 4, 5]
B = [6, 7, 8, 9, 10]
And I need to be able to find the sum of the nth terms from both lists i.e. 1+6, 2+7, 3+8 etc
Could someone please tell me how to refer to items in both lists at the same time?
I read somewhere that I could do Sum = a[i] + b[i] but I'm not convinced on how that would work.
>>> import operator
>>> map(operator.add, A, B)
[7, 9, 11, 13, 15]
just to demonstrate Pythons elegance :-)
Use a list comprehension and zip:
[a + b for (a,b) in zip(A,B)]
Are these questions homework? Or self-study?
If you know the lists will be the same length, you could do this:
AB = [A[i] + B[i] for i in range(len(A))]
In Python 2, you might want to use xrange instead of range if your lists are quite large. I think that's an explicit, simple, readable, obvious way to do it, but some might differ.
If the lists might be different lengths, you have to decide how you want to handle the extra elements. Let's say you want to ignore the extra elements of whichever list is longer. Here are three ways to do it:
AB = [A[i] + B[i] for i in range(min(len(A), len(B)))]
AB = map(sum, zip(A, B))
AB = [a + b for a, b in zip(A, B)]
The downside of using zip is that it will allocate a list of tuples, which can be a lot of memory if your lists are already large. Using for i in xrange with subscripting won't allocate all that memory, or you can use itertools.izip:
import itertools
AB = map(sum, itertools.izip(A, B))
If you instead want to pretend the shorter list is padded with zeros, using itertools.izip_longest is the shortest answer:
import itertools
AB = map(sum, itertools.izip_longest(A, B, fillvalue=0))
or
import itertools
AB = [a + b for a, b in itertools.izip_longest(A, B, fillvalue=0)]
Although Jazz's solution works for 2 lists, what if you have more than 2 lists? Here's a solution:
def apply_elementwise_function(elements_in_iterables, function):
elementwise_function = lambda x, y: itertools.imap(function, itertools.izip(x, y))
return reduce(elementwise_function, elements_in_iterables)
a = b = c = [1, 2, 3]
>>> list(apply_elementwise_function([a, b, c], sum))
[3, 6, 9]
Hi You can try this too:
>>>a=[1,2,3,4,5]
>>>b=[6,7,8,9,10]
>>>c=[]
>>>for i in range(0,5):
c.append(a[i]+b[i])
>>> c
[7, 9, 11, 13, 15]

Categories