Related
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))
I have a 2d list, for example:
list1 = [[1,2],[3,4],[5,6],[7,8]]
and I want to find the sum of all the numbers at the n'th place of every element.
For example if I want the answer for 0, I would calculate:
my_sum = list1[0][0] + list1[1][0] + list1[2][0]
or
my_sum = 0
place = 0
for i in range(len(list1)):
my_sum += list1[i][place]
return my_sum
Output: 16
Is there a more elegant way to do this? Or one that uses only one line of code?
I mean as fictional code for example:
fictional_function(list1,place) = 16
Since you are looking for a functional solution, consider operator.itemgetter:
from operator import itemgetter
L = [[1,2],[3,4],[5,6],[7,8]]
res = sum(map(itemgetter(0), L)) # 16
For performance and simpler syntax, you can use a 3rd party library such as NumPy:
import numpy as np
A = np.array([[1,2],[3,4],[5,6],[7,8]])
res = A[:, 0].sum() # 16
As a generalization if you want multiple indices (e.g. 0 and 1) you could use reduce combined with and element-wise sum something like this:
from functools import reduce
def fictional_function(lst, *places):
s_places = set(places)
def s(xs, ys):
return [x + y for x, y in zip(xs, ys)]
return [x for i, x in enumerate(reduce(s, lst)) if i in s_places]
list1 = [[1, 2], [3, 4], [5, 6], [7, 8]]
print(fictional_function(list1, 0))
print(fictional_function(list1, 0, 1))
print(fictional_function(list1, *[1, 0]))
Output
[16]
[16, 20]
[16, 20]
The idea is that the function s sums two list element-wise, for example:
s([1, 2], [3, 4]) # [4, 6]
and with reduce apply s to a list of lists, finally filter the result for the intended indices (places) only.
list1 = [[1,2],[3,4],[5,6],[7,8]]
ind = 0
sum_ind = sum(list(zip(*list1))[ind])
The above can be even written as function taking list and the index as input and returns the sum of the common index.
What we do in the above is first we get all the same indexes to individual lists using zip and then chooses which index one has to be summed and passes the same to sum function.
I'm trying to build a poly-alphabetic cipher but I can't find a way of adding a smaller list into a larger list, I have tried with list comprehensions, but still cannot do it. Please help! I want the smaller list to keep adding the same numbers to the larger list
so lets say I have 2 lists like this:
x = [1,2,3]
y = [4,5,6,7,8,9]
z = [i + j for i,j in zip(x,y)]
the result is the following
print(z)
[5,7,9]
how can I make it so it is:
[5,7,9,8,10,12]
meaning it keeps adding the same numbers to the longer list,
thank you for the help
You can use itertools.cycle to loop back through x as needed
>>> import itertools
>>> x = [1,2,3]
>>> y = [4,5,6,7,8,9]
>>> z = [i + j for i, j in zip(itertools.cycle(x), y)]
>>> z
[5, 7, 9, 8, 10, 12]
This is the simplest way, I think:
z = [y[i] + x[i % len(x)] for i in range(len(y))]
x = [1,2,3]
y = [4,5,6,7,8,9]
z=[a+b for a,b in zip((x*(int(len(y)/len(x))))[:len(y)],y)]
How about this with zip
I'm running Python 2.7.
I have an array called "altitude" with the following points
[0,1,2,3,4,5,6,7,8,9]
I also have an array called "arming_pin"
[0,0,0,0,0,0,1,1,1,1]
In my program when arming_pin is greater than zero I would like to use the "altitude" array data points and ignore the previous points when "arming_pin" was = to 0. I would like to call this new array "altitude_new". The "altitude_new" array would look like:
[6,7,8,9]
How can I do create this new array in python? Using a conditional statement of some sort?
You can use zip function within a list comprehension to filter your array :
>>> f=[0,1,2,3,4,5,6,7,8,9]
>>> sec=[0,0,0,0,0,0,1,1,1,1]
>>>
>>> [i for i,j in zip(f,sec) if j]
[6, 7, 8, 9]
You can also use itertools.compress Which is more efficient when you are dealing with larger list :
>>> from itertools import compress
>>> list(compress(f,sec))
[6, 7, 8, 9]
Or use numpy.compress:
>>> import numpy as np
>>> np.compress(sec,f)
array([6, 7, 8, 9])
You can also use the compress method from itertools module, this way:
>>> import itertools as it
>>> l1 = [0,1,2,3,4,5,6,7,8,9]
>>> l2 = [0,0,0,0,0,0,1,1,1,1]
>>> list(it.compress(l1,l2))
[6, 7, 8, 9]
altitude_new=[]
for i in range(len(arming_pin)):
if arming_pin[i] == 1:
altitude_new.append(altitude[i])
one line list comprehension:
altitude_new = [altitude[i] for i in range(len(arming_pin)) if arming_pin[i]]
night shade's comment is now more succinct [j for i,j in enumerate(altitude) if arming_pin[i]]
This is my solution, is meant to be easy to understand for people not accustomed to list comprehension.
altitude = [0,1,2,3,4,5,6,7,8,9]
arming_pin = [0,0,0,0,0,0,1,1,1,1]
altitude_new = []
idx = 0 # track the indices
for item in arming_pin:
if item > 0:
altitude_new.append(altitude[idx])
idx += 1
print altitude_new
>>> [6, 7, 8, 9]
If I have list=[1,2,3] and I want to add 1 to each element to get the output [2,3,4],
how would I do that?
I assume I would use a for loop but not sure exactly how.
new_list = [x+1 for x in my_list]
The other answers on list comprehension are probably the best bet for simple addition, but if you have a more complex function that you needed to apply to all the elements then map may be a good fit.
In your example it would be:
>>> map(lambda x:x+1, [1,2,3])
[2,3,4]
>>> mylist = [1,2,3]
>>> [x+1 for x in mylist]
[2, 3, 4]
>>>
list-comprehensions python.
if you want to use numpy there is another method as follows
import numpy as np
list1 = [1,2,3]
list1 = list(np.asarray(list1) + 1)
Edit: this isn't in-place
Firstly don't use the word 'list' for your variable. It shadows the keyword list.
The best way is to do it in place using splicing, note the [:] denotes a splice:
>>> _list=[1,2,3]
>>> _list[:]=[i+1 for i in _list]
>>> _list
[2, 3, 4]
>>> [x.__add__(1) for x in [1, 3, 5]]
3: [2, 4, 6]
My intention here is to expose if the item in the list is an integer it supports various built-in functions.
Python 2+:
>>> mylist = [1,2,3]
>>> map(lambda x: x + 1, mylist)
[2, 3, 4]
Python 3+:
>>> mylist = [1,2,3]
>>> list(map(lambda x: x + 1, mylist))
[2, 3, 4]
import numpy as np
np.add([1, 2, 3], 1).tolist()
which gives
[2, 3, 4]
Came across a not so efficient, but unique way of doing it. So sharing it across.And yes it requires extra space for another list.
from operator import add
test_list1 = [4, 5, 6, 2, 10]
test_list2 = [1] * len(test_list1)
res_list = list(map(add, test_list1, test_list2))
print(test_list1)
print(test_list2)
print(res_list)
#### Output ####
[4, 5, 6, 2, 10]
[1, 1, 1, 1, 1]
[5, 6, 7, 3, 11]
list = [1,2,3,4,5]
for index in range(len(list)):
list[index] = list[index] +1
print(list)
Just in case anyone was looking for a solution that only uses built-ins and no lambdas:
from functools import partial
from operator import add
my_list = range(1, 4) # list(my_list) #=> [1, 2, 3]
my_list_plus_one = list(map(partial(add, 1), my_list) #=> [2, 3, 4]
Many of the answers above are very good. I've also seen some weird answers that will do the job. Also, the last answer seen was through a normal loop. This willingness to give answers leads me to itertools and numpy, which will do the same job in a different way.
Here I present different ways to do the job, not answered above.
import operator
import itertools
x = [3, 5, 6, 7]
integer = 89
"""
Want more vairaint can also use zip_longest from itertools instead just zip
"""
#lazy eval
a = itertools.starmap(operator.add, zip(x, [89] * len(x))) # this is not subscriptable but iterable
print(a)
for i in a:
print(i, end = ",")
# prepared list
a = list(itertools.starmap(operator.add, zip(x, [89] * len(x)))) # this returns list
print(a)
# With numpy (before this, install numpy if not present with `pip install numpy`)
import numpy
res = numpy.ones(len(x), dtype=int) * integer + x # it returns numpy array
res = numpy.array(x) + integer # you can also use this, infact there are many ways to play around
print(res)
print(res.shape) # prints structure of array, i.e. shape
# if you specifically want a list, then use tolist
res_list = res.tolist()
print(res_list)
Output
>>> <itertools.starmap object at 0x0000028793490AF0> # output by lazy val
>>> 92,94,95,96, # output of iterating above starmap object
>>> [92, 94, 95, 96] # output obtained by casting to list
>>> __
>>> # |\ | | | |\/| |__| \ /
>>> # | \| |__| | | | |
>>> [92 94 95 96] # this is numpy.ndarray object
>>> (4,) # shape of array
>>> [92, 94, 95, 96] # this is a list object (doesn't have a shape)
My sole reason to highlight the use of numpy is that one should always do such manipulations with libraries like numpy because it is performance efficient for very large arrays.