If I have a list containing a lambda function, for example:
a = [lambda x: x * 2]
how could I call this lambda function to a list:
b = [1,2,3,4]
so that it could have the result as:
result = list(map(lambda x: x * 2, b))
and get:
[2,4,6,8]
Further, what if a contains two lambda functions, for example:
a = [lambda x:x * 2, lambda x: x-1]
How could I call these functions to list b without using for loop or list comprehension but use map()?
I hope someone could help me with it!
You can simply do
result = list(map(a[0], b))
# [2,4,6,8]
since the lambda function is the first element of a
For the second function it's the same thing
result = list(map(a[1], b))
If you want to apply all functions in one line
[list(map(a[i],b)) for i in range(len(a))]
#[[2, 4, 6, 8], [0, 1, 2, 3]]
You can iterate over the lambda functions in the list no matter how many elements stored in it:
a = [lambda x:x * 2, lambda x: x-1]
b = [1, 2, 3, 4]
for func in a:
# apply each function on b and turn the results to list:
print(list(map(func, b)))
If you want to store each result:
a = [lambda x:x * 2, lambda x: x-1]
b = [1, 2, 3, 4]
results = []
for func in a:
results.append(list(map(func, b)))
In the special case of a single lambda wrapped in a list, do
result = list(map(a[0], b))
But there are no special cases in python. So for the general case, you can either have a flat list:
result = [f(x) for f in a for x in b]
or a nested one:
result = [[f(x) for f in a] for x in b]
You can reverse the sort order of the lists by swapping the loops over a and b.
You can even go as far as using itertools.product to get the flat case (again with a and b interchangeable to change the order of the result):
result = [f(x) for f, x in itertools.product(a, b)]
This question already has answers here:
How do I iterate through two lists in parallel?
(8 answers)
Apply function to each element of a list
(4 answers)
Closed 8 months ago.
I want to perform an element wise multiplication, to multiply two lists together by value in Python, like we can do it in Matlab.
This is how I would do it in Matlab.
a = [1,2,3,4]
b = [2,3,4,5]
a .* b = [2, 6, 12, 20]
A list comprehension would give 16 list entries, for every combination x * y of x from a and y from b. Unsure of how to map this.
If anyone is interested why, I have a dataset, and want to multiply it by Numpy.linspace(1.0, 0.5, num=len(dataset)) =).
Use a list comprehension mixed with zip():.
[a*b for a,b in zip(lista,listb)]
Since you're already using numpy, it makes sense to store your data in a numpy array rather than a list. Once you do this, you get things like element-wise products for free:
In [1]: import numpy as np
In [2]: a = np.array([1,2,3,4])
In [3]: b = np.array([2,3,4,5])
In [4]: a * b
Out[4]: array([ 2, 6, 12, 20])
Use np.multiply(a,b):
import numpy as np
a = [1,2,3,4]
b = [2,3,4,5]
np.multiply(a,b)
You can try multiplying each element in a loop. The short hand for doing that is
ab = [a[i]*b[i] for i in range(len(a))]
Yet another answer:
-1 ... requires import
+1 ... is very readable
import operator
a = [1,2,3,4]
b = [10,11,12,13]
list(map(operator.mul, a, b))
outputs [10, 22, 36, 52]
Edit
For Python3.6+ map does not automatically unpack values.
Use itertools.starmap
import itertools
import operator
itertools.starmap(operator.mul, zip(a, b)))
you can multiplication using lambda
foo=[1,2,3,4]
bar=[1,2,5,55]
l=map(lambda x,y:x*y,foo,bar)
Fairly intuitive way of doing this:
a = [1,2,3,4]
b = [2,3,4,5]
ab = [] #Create empty list
for i in range(0, len(a)):
ab.append(a[i]*b[i]) #Adds each element to the list
gahooa's answer is correct for the question as phrased in the heading, but if the lists are already numpy format or larger than ten it will be MUCH faster (3 orders of magnitude) as well as more readable, to do simple numpy multiplication as suggested by NPE. I get these timings:
0.0049ms -> N = 4, a = [i for i in range(N)], c = [a*b for a,b in zip(a, b)]
0.0075ms -> N = 4, a = [i for i in range(N)], c = a * b
0.0167ms -> N = 4, a = np.arange(N), c = [a*b for a,b in zip(a, b)]
0.0013ms -> N = 4, a = np.arange(N), c = a * b
0.0171ms -> N = 40, a = [i for i in range(N)], c = [a*b for a,b in zip(a, b)]
0.0095ms -> N = 40, a = [i for i in range(N)], c = a * b
0.1077ms -> N = 40, a = np.arange(N), c = [a*b for a,b in zip(a, b)]
0.0013ms -> N = 40, a = np.arange(N), c = a * b
0.1485ms -> N = 400, a = [i for i in range(N)], c = [a*b for a,b in zip(a, b)]
0.0397ms -> N = 400, a = [i for i in range(N)], c = a * b
1.0348ms -> N = 400, a = np.arange(N), c = [a*b for a,b in zip(a, b)]
0.0020ms -> N = 400, a = np.arange(N), c = a * b
i.e. from the following test program.
import timeit
init = ['''
import numpy as np
N = {}
a = {}
b = np.linspace(0.0, 0.5, len(a))
'''.format(i, j) for i in [4, 40, 400]
for j in ['[i for i in range(N)]', 'np.arange(N)']]
func = ['''c = [a*b for a,b in zip(a, b)]''',
'''c = a * b''']
for i in init:
for f in func:
lines = i.split('\n')
print('{:6.4f}ms -> {}, {}, {}'.format(
timeit.timeit(f, setup=i, number=1000), lines[2], lines[3], f))
For large lists, we can do it the iter-way:
product_iter_object = itertools.imap(operator.mul, [1,2,3,4], [2,3,4,5])
product_iter_object.next() gives each of the element in the output list.
The output would be the length of the shorter of the two input lists.
create an array of ones;
multiply each list times the array;
convert array to a list
import numpy as np
a = [1,2,3,4]
b = [2,3,4,5]
c = (np.ones(len(a))*a*b).tolist()
[2.0, 6.0, 12.0, 20.0]
Can use enumerate.
a = [1, 2, 3, 4]
b = [2, 3, 4, 5]
ab = [val * b[i] for i, val in enumerate(a)]
The map function can be very useful here.
Using map we can apply any function to each element of an iterable.
Python 3.x
>>> def my_mul(x,y):
... return x*y
...
>>> a = [1,2,3,4]
>>> b = [2,3,4,5]
>>>
>>> list(map(my_mul,a,b))
[2, 6, 12, 20]
>>>
Of course:
map(f, iterable)
is equivalent to
[f(x) for x in iterable]
So we can get our solution via:
>>> [my_mul(x,y) for x, y in zip(a,b)]
[2, 6, 12, 20]
>>>
In Python 2.x map() means: apply a function to each element of an iterable and construct a new list.
In Python 3.x, map construct iterators instead of lists.
Instead of my_mul we could use mul operator
Python 2.7
>>>from operator import mul # import mul operator
>>>a = [1,2,3,4]
>>>b = [2,3,4,5]
>>>map(mul,a,b)
[2, 6, 12, 20]
>>>
Python 3.5+
>>> from operator import mul
>>> a = [1,2,3,4]
>>> b = [2,3,4,5]
>>> [*map(mul,a,b)]
[2, 6, 12, 20]
>>>
Please note that since map() constructs an iterator we use * iterable unpacking operator to get a list.
The unpacking approach is a bit faster then the list constructor:
>>> list(map(mul,a,b))
[2, 6, 12, 20]
>>>
To maintain the list type, and do it in one line (after importing numpy as np, of course):
list(np.array([1,2,3,4]) * np.array([2,3,4,5]))
or
list(np.array(a) * np.array(b))
you can use this for lists of the same length
def lstsum(a, b):
c=0
pos = 0
for element in a:
c+= element*b[pos]
pos+=1
return c
import ast,sys
input_str = sys.stdin.read()
input_list = ast.literal_eval(input_str)
list_1 = input_list[0]
list_2 = input_list[1]
import numpy as np
array_1 = np.array(list_1)
array_2 = np.array(list_2)
array_3 = array_1*array_2
print(list(array_3))
From this thread we can see, how to unpack multiple return values from list comprehension to a tuple.
def f(x):
return 2*x, x*x
x = range(1, 4)
xlist, ylist = zip(*[f(value) for value in x])
Is there a way to do this straight to a numpy array? Or is the only solution to to this with:
xlist = np.asarray(xlist)
?
To do this with a numpy.array, simply pass the argument as an array itself. The operations in the function get mapped over the array argument and a tuple of two arrays is returned:
>>> xlist, ylist = f(np.asarray(x))
>>> xlist
array([2, 4, 6])
>>> ylist
array([1, 4, 9])
You may use:
xlist,ylist = np.fromiter(
itertools.chain.from_iterable(f(value) for value in x),
dtype=np.int_,
count=len(x)*2
).reshape((-1,2)).T
or
xlist,ylist = np.array([f(value) for value in x]).T
However, the approaches directly working on arrays, as proposed by the other answers, could be more readable and would be also faster.
No need for zip or list comprehensions. You also don't need to change your f function:
>>> import numpy as np
>>> x = np.arange(1, 4)
>>> array1, array2 = f(x)
>>> array1
array([2, 4, 6])
>>> array2
array([1, 4, 9])
If x is an array, 2 * x means that each element of x will be multiplied by 2:
>>> 2 * x
array([2, 4, 6])
I have 2D list and I need to search for the index of an element. As I am begineer to programming I used the following function:
def in_list(c):
for i in xrange(0,no_classes):
if c in classes[i]:
return i;
return -1
Here classes is a 2D list and no_classes denotes the number of classes i.e the 1st dimesntion of the list. -1 is returned when c is not in the araray. Is there any I can optimize the search?
You don't need to define no_classes yourself. Use enumerate():
def in_list(c, classes):
for i, sublist in enumerate(classes):
if c in sublist:
return i
return -1
Use list.index(item)
a = [[1,2],[3,4,5]]
def in_list(item,L):
for i in L:
if item in i:
return L.index(i)
return -1
print in_list(3,a)
# prints 1
if order doesn't matter and you have no duplicates in your data, I suggest to turn you 2D list into list of sets:
>>> l = [[1, 2, 4], [6, 7, 8], [9, 5, 10]]
>>> l = [set(x) for x in l]
>>> l
[set([1, 2, 4]), set([8, 6, 7]), set([9, 10, 5])]
After that, your original function will work faster, because search of element in set is constant (while search of element in list is linear), so you algorithm becomes O(N) and not O(N^2).
Note that you should not do this in your function or it would be converted each time function is called.
If your "2D" list is rectangular (same number of columns for each line), you should convert it to a numpy.ndarray and use numpy functionalities to do the search. For an array of integers, you can use == for comparison. For an array of float numbers, you should use np.isclose instead:
a = np.array(c, dtype=int)
i,j = np.where(a == element)
or
a = np.array(c, dtype=float)
i,j = np.where(np.isclose(a, element))
such that i and j contain the line and column indices, respectively.
Example:
a = np.array([[1, 2],
[3, 4],
[2, 6]], dtype=float)
i, j = np.where(np.isclose(a, 2))
print(i)
#array([0, 2])
print(j)
#array([1, 0]))
using list comprehension: (2D list to 1D)
a = [[1,22],[333,55555,6666666]]
d1 = [x for b in a for x in b]
print(d1)
anyone have any idea how to unpack the values in a tuple for a list comprehension?
So a practical example:
def func(x,y):
return x*2, y*2
x = [1, 2, 3]; y = [1, 2, 3]
a, b = [ func(i,j) for i, j in zip(x,y) ]
Unfortunately, that gives me an error sayin' there are too many values to unpack...
I've tried
zip(*func(i,j))
(a,b) = ...
Do you mean the following?:
a, b = zip(*[func(i,j) for i, j in zip(x,y)])
for x1,y1 in [func(i,j) for i, j in zip(x,y)]:
# do something with x1,y1
The problem is that the list comprehension returns something like
[(1,1), (4,4), (6,6),..]
so the list contains more than just two elements.
I don't see why you can't just do:
a = [i*2 for i in x]
b = [i*2 for i in y]
If you are worried about duplicate code, create a function:
def func(l):
return [i*2 for i in l]
a, b = func(x), func(y)
Trying to pack everything in one line, using fancy list unpacking etc., does not necessarily increase readability.