list comprehension in matrix multiplication in python 3.x - python-3.x

I have found a code of Matrix Multiplication in Python 3.x but I am not able to understand how list comprehension is working in the below code.
# Program to multiply two matrices using list comprehension
# 3x3 matrix
X = [[12,7,3],
[4 ,5,6],
[7 ,8,9]]
# 3x4 matrix
Y = [[5,8,1,2],
[6,7,3,0],
[4,5,9,1]]
# result is 3x4
result = [[sum(a*b for a,b in zip(X_row,Y_col)) for Y_col in zip(*Y)] for X_row in X]
for r in result:
print(r)

#Santosh, it's probably easier to understand this List Comprehension from pure loop way, like this:
# 3x3 matrix
X = [[12,7,3],
[4,5,6],
[7,8,9]]
# 3x4 matrix
Y = [[5,8,1,2],
[6,7,3,0],
[4,5,9,1]]
# result is 3x4
result = [[0,0,0,0],
[0,0,0,0],
[0,0,0,0]]
# iterate through rows of X
for r in range(len(X)):
# iterate through columns of Y
for c in range(len(Y[0])):
# iterate through rows of Y
for k in range(len(Y)):
result[r][c] += X[r][k] * Y[k][c]
print(result)
Then you prob. can find the similarity with the List Comprehension version, with little reformatting:
def matrix_mul(X, Y):
zip_b = list(zip(*Y))
return [[sum(a * b for a, b in zip(row_a, col_b))
for col_b in zip_b]
for row_a in X]

Related

How to merge multiple tuples or lists in to dictionary using loops?

Here is my code to merge all tuple in to dictionary,
x = (1,2,3)
y = ('car',"truck","plane")
z=("merc","scania","boeing")
products={}
for i in x,y,z:
products[x[i]]= {y[i]:z[i]}
output:
error:
6 for i in x,y,z:
----> 7 products[x[i]]= {y[i]:z[i]}
8
9 print(products)
TypeError: tuple indices must be integers or slices, not a tuple
Now if i use indexing method inside loop for identifying positions like below code,
for i in x,y,z:
products[x[0]]= {y[0]:z[0]}
print(products)
out:
{1: {'car': 'merc'}}
here, I could only create what I need but only for a specified index how do create a complete dictionary using multiple lists/tuples??
is it also possible to use Zip & map functions?
Use zip to iterate over your separate iterables/tuples in parallel
list(zip(x, y, z)) # [(1, 'car', 'merc'), (2, 'truck', 'scania'), (3, 'plane', 'boeing')]
x = (1, 2, 3)
y = ("car", "truck", "plane")
z = ("merc", "scania", "boeing")
products = {i: {k: v} for i, k, v in zip(x, y, z)}
print(products) # {1: {'car': 'merc'}, 2: {'truck': 'scania'}, 3: {'plane': 'boeing'}}
You should use integer as indices.
x = (1,2,3)
y = ('car',"truck","plane")
z=("merc","scania","boeing")
products={}
for i in range(len(x)):
products[x[i]]= {y[i]:z[i]}
This should solve your problem
To add for above answer, I'm posting a solution using map,
x = (1,2,3)
y = ('car',"truck","plane")
z=("merc","scania","boeing")
products=dict(map(lambda x,y,z:(x,{y:z}),x,y,z))
print(products)

Loop over items in dicts in list using Python 3 comprehensions

Suppose I have a list with dicts, given is: each dict contains one key.
testlist = [{'x': 15}, {'y': 16}, {'z': 17}]
for x in testlist:
for k, v in x.items():
print(k,v)
# x 15
# y 16
# z 17
How can I use comprehensions to get the same result?
I tried this:
for k,v in [x.items() for x in testlist]:
print(k,v)
Returns: ValueError: not enough values to unpack (expected 2, got 1)
You have to make a multiloop comprehension:
for k,v in [pair for x in testlist for pair in x.items()]:
or use itertools.chain to do the flattening for you (somewhat more efficiently):
from itertools import chain
for k, v in chain.from_iterable(x.items() for x in testlist):
# Or with operator.methodcaller to move the work to the C layer:
for k, v in chain.from_iterable(map(methodcaller('items'), testlist)):

How to multiply 2 input lists in python

Please help me understand how to code the following task in Python using input
Programming challenge description:
Write a short Python program that takes two arrays a and b of length n
storing int values, and returns the dot product of a and b. That is, it returns
an array c of length n such that c[i] = a[i] · b[i], for i = 0,...,n−1.
Test Input:
List1's input ==> 1 2 3
List2's input ==> 2 3 4
Expected Output: 2 6 12
Note that the dot product is defined in mathematics to be the sum of the elements of the vector c you want to build.
That said, here is a possibiliy using zip:
c = [x * y for x, y in zip(a, b)]
And the mathematical dot product would be:
sum(x * y for x, y in zip(a, b))
If the lists are read from the keyboard, they will be read as string, you have to convert them before applying the code above.
For instance:
a = [int(s) for s in input().split(",")]
b = [int(s) for s in input().split(",")]
c = [x * y for x, y in zip(a, b)]
Using for loops and appending
list_c = []
for a, b in zip(list_a, list_b):
list_c.append(a*b)
And now the same, but in the more compact list comprehension syntax
list_c = [a*b for a, b in zip(list_a, list_b)]
From iPython
>>> list_a = [1, 2, 3]
>>> list_b = [2, 3, 4]
>>> list_c = [a*b for a, b in zip(list_a, list_b)]
>>> list_c
[2, 6, 12]
The zip function packs the lists together, element-by-element:
>>> list(zip(list_a, list_b))
[(1, 2), (2, 3), (3, 4)]
And we use tuple unpacking to access the elements of each tuple.
From fetching the input and using map & lambda functions to provide the result. If you may want to print the result with spaces between (not as list), use the last line
list1, list2 = [], []
list1 = list(map(int, input().rstrip().split()))
list2 = list(map(int, input().rstrip().split()))
result_list = list(map(lambda x,y : x*y, list1, list2))
print(*result_list)
I came out with two solutions. Both or them are the ones that are expected in a Python introductory course:
#OPTION 1: We use the concatenation operator between lists.
def dot_product_noappend(list_a, list_b):
list_c = []
for i in range(len(list_a)):
list_c = list_c + [list_a[i]*list_b[i]]
return list_c
print(dot_product_noappend([1,2,3],[4,5,6])) #FUNCTION CALL TO SEE RESULT ON SCREEN
#OPTION 2: we use the append method
def dot_product_append(list_a, list_b):
list_c = []
for i in range(len(list_a)):
list_c.append(list_a[i]*list_b[i])
return list_c
print(dot_product_append([1,2,3],[4,5,6])) #FUNCTION CALL TO SEE RESULT ON SCREEN
Just note that the first method requires that you cast the product of integers to be a list before you can concatenate it to list_c. You do that by using braces ([[list_a[i]*list_b[i]] instead of list_a[i]*list_b[i]). Also note that braces are not necessary in the last method, because the append method does not require to pass a list as parameter.
I have added the two function calls with the values you provided, for you to see that it returns the correct result. Choose whatever function you like the most.

How to insert z values onto x,y coordinates?

I have three list, which has some repeated values. I am using them as x and y coordinates. Thus, my third list is corresponds to the values that I want to plot as a heatmap.
For now, I can assign the values of z for only one list, how can I make a for loop to do the same for the rest of the grid?
x = [1,1,1,2,2,2,3,3,3]
y = [1,2,3,1,2,3,1,2,3]
z = [5.9617e-09,6.3562e-09,6.819e-09,7.3562e-09,7.989e-09,8.6735e-
09,9.3898e-09,1.0139e-08,1.0912e-08,1.0912e-08]
xs = len(set(x))
ys = len(set(y))
grid = []
counter = 0
for row in range(ys):
rows = [] # creating the rows on the grid
if len(rows) < ys: # I want to loop over ys and assign the values os z to each coordinate
grid.append(z[counter])
counter = counter+1
print(grid)
Once I have a 2d array, then I can use the heatmap to plot it nicely.
The easiest way is to use numpy:
In [1]: z = [5.9617e-09,6.3562e-09,6.819e-09,7.3562e-09,
7.989e-09,8.6735e-09,9.3898e-09,1.0139e-08,
1.0912e-08,1.0912e-08]
In [2]: len(z)
Out[2]: 10
In [3]: import numpy as np
Ten numbers don't fit in a 3x3 grid, so skip the last one.
In [4]: nz = np.array(z[:-1])
Out[4]:
array([5.9617e-09, 6.3562e-09, 6.8190e-09, 7.3562e-09, 7.9890e-09,
8.6735e-09, 9.3898e-09, 1.0139e-08, 1.0912e-08])
In [5]: nz.reshape((3,3))
Out[5]:
array([[5.9617e-09, 6.3562e-09, 6.8190e-09],
[7.3562e-09, 7.9890e-09, 8.6735e-09],
[9.3898e-09, 1.0139e-08, 1.0912e-08]])
A plain Python solution using itertools and functools:
In [6]: import itertools as it
...: import functools as ft
In [7]: def chunked(iterable, n): # {{{1
...: def take(n, iterable):
...: return list(it.islice(iterable, n))
...: return iter(ft.partial(take, n, iter(iterable)), [])
...:
In [8]: list(chunked(z[:-1], 3))
Out[8]:
[[5.9617e-09, 6.3562e-09, 6.819e-09],
[7.3562e-09, 7.989e-09, 8.6735e-09],
[9.3898e-09, 1.0139e-08, 1.0912e-08]]

Permutations in a list

I have a list containing n integers. The ith element of the list a, a[i], can be swapped into any integer x such that 0 ≤ x ≤ a[i]. For example if a[i] is 3, it can take values 0, 1, 2, 3.
The task is to find all permutations of such list. For example, if the list is
my_list = [2,1,4]
then the possible permutations are:
[0,0,0], [0,0,1], ... [0,0,4],
[0,1,0], [0,1,1], ... [0,1,4],
[1,0,0], [1,0,1], ... [1,0,4],
[1,1,0], [1,1,1], ... [1,1,4],
[2,0,0], [2,0,1], ... [2,0,4],
[2,1,0], [2,1,1], ... [2,1,4]
How to find all such permutations?
you could use a comibation of range to get all the 'valid' values for each element of the list and itertools.product:
import itertools
my_list = [2,1,4]
# get a list of lists with all the possible values
plist = [list(range(y+1)) for y in my_list]
#
permutations = sorted(list(itertools.product(*plist)))
more on itertools product see e.g. here on SO or the docs.
Here's a solution:
my_list=[2,1,4]
def premutation_list(p_list):
the_number=int("".join(map(str,p_list)))
total_len=len(str(the_number))
a=[i for i in range(the_number)]
r_list=[]
for i in a:
if len(str(i))<total_len:
add_rate=total_len - len(str(i))
b="0,"*add_rate
b=b.split(",")
b=b[0:len(b)-1]
b.append(str(i))
r_list.append([int(y) for x in b for y in x ])
else:
r_list.append([int(x) for x in str(i)])
return r_list
print(premutation_list(my_list))
Explanation:
The basic idea is just getting all the numbers till the given number. For example till 4 there are 0,1,2,3, number.
I have achieved this first by converting the list into a integer.
Then getting all the numbers till the_number.
Try this. Let me know if I misunderstood your question
def permute(l,cnt,n):
if cnt==n:
print(l)
return
limit = l[cnt]
for i in range(limit+1):
l[cnt]=i
permute(l[:n],cnt+1,n)
l =[2,1,4]
permute(l,0,3)

Resources