I want to create a new list (V) from other lists (a, b, c) and using a function, but I would like to take advantage of python and apply the function to the three lists and not element by element.
For example, I have the lists a, b and c; and the result after apply the function should be V. Thanks.
def mag(a, b, c):
# something sophisticated
return (a+b)*c
a = [1, 5, 7]
b = [4, 8, 3]
c = [2, 6, 3]
V = [10, 78, 30]
You can easily do this with the map function:
V = list(map(mag, a, b, c))
You want to first zip the arguments, then map the function on the unpacked tuples:
from itertools import starmap
starmap(mag, zip(a,b,c))
See here for an example.
An alternate solution is to use map and lambda
In [16]: list(map(lambda p: mag(*p), zip(a, b, c)))
Out[16]: [10, 78, 30]
What about using only built-in functions? Like zip
>>> [mag(a_, b_, c_) for a_,b_,c_ in zip(a, b, c)]
[10, 78, 30]
Plus another python buit-in function, map which returns an
iterator and thus makes things go faster and ends up saving memory:
>>> gen = map(lambda uple:mag(*uple), zip(a, b, c))
>>> list(gen)
[10, 78, 30]
Related
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]
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.
I need to perform a calculation on a list using both the values of that list, and the index of those values, eg:
a = [1,2,3,4,5]
b= a[1]*1
but for all values of a, to get:
b = [1,4,9,16,25]
Is this possible to do without a for loop? I could put it in one, but it would change the structure of my code for the worse. This is meant to be used by a wide variety of users with varying skill levels, so I'm willing to sacrifice speed for ease of readability.
You can use list comprehension and enumerate() function, that provides the index as well as value of the element, simultaneously. Example -
b = [elem * (i+1) for i, elem in enumerate(a)]
Demo -
>>> a = [1,2,3,4,5]
>>> b = [elem * (i+1) for i, elem in enumerate(a)]
>>> b
[1, 4, 9, 16, 25]
If its fine to use numpy library , most probably a faster solution would be to use numpy's vectorised multiplication . Example -
In [1]: import numpy as np
In [2]: a = [1,2,3,4,5]
In [3]: a_arr = np.array(a)
In [4]: b = a_arr * np.arange(1,a_arr.shape[0]+1)
In [5]: b
Out[5]: array([ 1, 4, 9, 16, 25])
Though numpy method may be a bit more complex to understand that the list comprehension.
I recommend you to use map built-in function and let your code be simpler.
a = [1,2,3,4,5]
b = map(lambda x: x*x, a)
print b
# [1, 4, 9, 16, 25]
If you want to dynamically enter your list, you would use range built-in function (It's available for python2):
b = map(lambda x: x*x, range(1,6))
print b
# [1, 4, 9, 16, 25]
Given two lists of equal length, is there a simpler or preferred way to iterate over two lists of equal length and append the maximum of each pair of elements to a new list? These are the two methods I know of.
import itertools
a = [1,2,3,4,5]
b = [1,1,6,3,8]
m1 = list()
m2 = list()
for x, y in zip(a, b):
m1.append(max(x, y))
for x in itertools.imap(max, a, b):
m2.append(x)
Both of these result in [1, 2, 6, 4, 8], which is correct. Is there a better way?
map(max, a, b)
[max(x, y) for x, y in zip(a, b)]
You could do it like:
a = [1,2,3,4,5]
b = [1,1,6,3,8]
m3 = [max(x,y) for (x,y) in zip(a,b)]
or even
m4 = map(max, zip(a,b))
In Python3, map() no longer returns a list, so you should use the list comprehension or
list(map(max, a, b))
if you really need a list and not just an iterator
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]