Lets start with what you were trying. The for loop:
a = [1,2,3]
b = [4,5,6]
ab = []
for x in a:
for y in b:
ab.append(x * y)
print(ab)
[4, 5, 6, 8, 10, 12, 12, 15, 18]
Now, I would suggest you have a read here python data structures
Once you understand how to use a for loop, understanding list comprehensions is easy.
The are the same for loop, but but the results go straight into a list. this is nice. In-fact it is so nice that nearly everybody does it this way.
a = [1,2,3]
b = [4,5,6]
ab = [ x * y for x in a for y in b ]
print(ab)
[4, 5, 6, 8, 10, 12, 12, 15, 18]
so, instead of for ... ab.append(x * y)
we write [ x * y for ... ]
now if the code was written like this:
ab = ( x * y for x in a for y in b )
it would make it a generator. Lots of people use these as well. Think of these as lazy lists. You can put things in it, but it is not evaluated until you try and do something with it.
print(ab)
<generator object <genexpr> at 0x4d7058>
print( list(ab) )
[4, 5, 6, 8, 10, 12, 12, 15, 18]
if you 'were' trying to solve this using the indexes, I would probably use:
[a[x] * b[y] for x,_a in enumerate(a) for y,_b in enumerate(b)]
you can also do fun things like:
from operator import mul
a = [1,2,3]
b = [4,5,6]
ab = list(map(mul, a,b))
print(ab)
[4, 10, 18]
if you used:
ab = map(mul, a,b)
you would create a map object... which is very much the same as the < generator >
.
print(ab)
>>> <map object at 0x4d4eb0>
print( list(ab) )
>>> [4, 10, 18]
or if you had three lists:
a = [1,2,3]
b = [4,5,6]
c = [7,8,9]
abc = list(map(lambda x,y,z: x * y * z, a,b,c))
print(abc)
[28, 80, 162]
and if you really wanted to you could do:
from itertools import product
from functools import reduce
from operator import mul
a = [1,2,3]
b = [4,5,6]
ab = list(map(lambda x: reduce(mul,x), product(a,b)))
--or--
ab = list(map(lambda x: mul(*x), product(a,b)))
print(ab)
[4, 5, 6, 8, 10, 12, 12, 15, 18]