List comprehension over 2 independent lists - python

I have two lists like:
a = [10, 35, 57, 79]
b = [13, 41, 65, 80]
I want to get list with pairs of a number and value, where value is True for elements from the list a.
I can do it with;
a_list = [(item, True) for item in a]
b_list = [(item, False) for item in b]
result = a_list + b_list
Is it possible to union these two list comprehensions and make the code simpler?

I can suggest:
list(zip(a + b, [True] * len(a) + [False] * len(b)))

you can use this:
[y for x in [list1, list2] for y in x]
a = [10, 35, 57, 79]
b = [13, 41, 65, 80]
result = [y for x in [[(item, True) for item in a], [(item, False) for item in b]] for y in x]

Related

Given two matrices, print the product of those matrices

I have to check if the given matrices can be multiplied, and if yes, return the product.
I cannot use numpy to calculate the product.
Example used:
A = [[1,2],[3,4]]
B = [[1,2,3,4,5],[5,6,7,8,9]]
Expected output: A*B = [[11,14,17,20,23],[23,30,37, 44,51]]
Here's my code and output:
def matrix_mult(A,B):
countA = 0
countB = 0
result = [[0]*len(B[0])]*len(A)
for i in range(len(A)):
if A[i][1]:
countA += 1
for i in range(len(B)):
if B:
countB += 1
if countA == countB:
for i in range(len(A)):
for j in range(len(B[0])):
for k in range(len(A)):
result[i][j] += A[i][k]*B[k][j]
return result
A = [[1,2],[3,4]]
B = [[1,2,3,4,5], [5,6,7,8,9]]
matrix_mult(A,B)
output:
[[34, 44, 54, 64, 74], [34, 44, 54, 64, 74]]
Is there something wrong with the code/logic?
The guilty is your result declaration. It's not a good way to declare a list by duplicating the elements (not creating a proper matrix). More details in this discussion.
Try:
result = [[0 for _ in range(len(B[0]))] for _ in range(len(A))]
Instead of:
result = [[0] * len(B[0]) ] * len(A)
And that should work fine !
Why make the code so long? You can try this -
def dot(A, B):
return [[sum(x*y for x, y in zip(A_row, B_column)) for B_column in zip(*B)] for A_row in A]
A = [[1,2],[3,4]]
B = [[1,2,3,4,5],[5,6,7,8,9]]
result = dot(A, B)
print(result)
#[[11, 14, 17, 20, 23], [23, 30, 37, 44, 51]]
See if this helps you.
I will recommend using numpy:
import numpy as np
A = np.array([[1,2],[3,4]])
B = np.array([[1,2,3,4,5],[5,6,7,8,9]])
np.matmul(A, B)
# output : array([[11, 14, 17, 20, 23],
# [23, 30, 37, 44, 51]])
with your code there are several issues, below I was trying to improve your code:
def matrix_mult(A,B):
num_col_a = len(A[0])
num_rows_b = len(B)
result = [[0 for _ in range(len(B[0]))] for _ in range(len(A))]
if num_col_a == num_rows_b:
for row_a_index, row_a in enumerate(A):
for col_index, col_b in enumerate(zip(*B)):
result[row_a_index][col_index] = sum(a * b for a, b in zip(row_a, col_b))
return result
A = [[1,2],[3,4]]
B = [[1,2,3,4,5], [5,6,7,8,9]]
print(matrix_mult(A,B))
# output: [[11, 14, 17, 20, 23], [23, 30, 37, 44, 51]]

Having trouble mapping a list to a list of lists in python

Essentially, I need to create a new list of lists from a value list that maps to another interval list. Some of these values actually fall in the range of two sublists in the intervals. For instance, 25 falls between [0,30] and between [20,55]. However an integer value such as 91 only falls in the range of one sublist [75,100]. I want to create a new list where each value maps to the interval list but I want these values separate from the interval list.
intervals = [[0,30], [20,55], [45,80], [75,100]]
values = [25, 51, 53, 83, 91]
Right now my code is as follows:
maplist = [[]]
for i in values:
for j in intervals:
if(i >= j[0]) and (i <= j[1]):
maplist.append(i)
print(maplist)
This ouputs to:
[[], 25, 25, 51, 51, 53, 53, 83, 91 ]
So, as you can see, Its outputting 25 twice, 51 twice and 53 twice because those values fall between various sublists. 83 and 91 only fall between [75-100]
I want the output to be:
[[25], [25,51,53], [51,53], [83,91]]
This means each value would map with the interval list of lists. Any help would be greatly appreciated.
List comprehensions?
>>> [[v for v in values if a <= v <= b] for a, b in intervals]
[[25], [25, 51, 53], [51, 53], [83, 91]]
So you could do it by looping through intervals first and getting all the values in that range. Like this:
intervals = [[0,30], [20,55], [45,80], [75,100]]
values = [25, 51, 53, 83, 91]
maplist = []
for i in intervals:
inrange = []
for v in values:
if v >= i[0] and v <= i[1]:
inrange.append(v)
maplist.append(inrange)
print(maplist)
This prints [[25], [25, 51, 53], [51, 53], [83, 91]]
The problem is that you are appending to maplist, which is initialized to be a list containing one element (another list). When you process 25, you append it to maplist, first once, at which point maplist is [[], 25] and then again for the next interval ([[], 25, 25]).
Instead, you want one list for each interval:
maplist = [[] for _ in range(len(intervals))]
for i in values:
for idx, j in enumerate(intervals):
if(i >= j[0]) and (i <= j[1]):
maplist[idx].append(i)
(If you're not familiar with enumerate, it produces pairs (index, item) for the items in a list.)
Use a list comprehension.
Also you are initializing the maplist with another list..
maplist = [[x for x in values if i <= x <= j] for i, j in intervals]
print(maplist)
You can use collections.defaultdict to create a better mapping of the occurrences of each each value item in intervals:
from collections import defaultdict
d = defaultdict(list)
intervals = [[0,30], [20,55], [45,80], [75,100]]
values = [25, 51, 53, 83, 91]
for i in values:
for c, h in enumerate(intervals):
if i >= h[0] and i <= h[-1]:
d[c].append(i)
final_result = [b for a, b in d.items()]
Output:
[[25], [25, 51, 53], [51, 53], [83, 91]]

Combine elements of two lists with if statement in python

I am trying to merge two lists depend on the criteria.
I have following codes.
R1=[10,20,30,40,50]
R2=[5,10,45,40,45]
for n,m in zip(R1,R2):
if n>m:
print(n)
else:
print(m)
When I run above code,the results is :
10
20
45
40
50
I don't know how to get that results as a new list like this:
results=[10,20,45,40,50]
How can I do this?
Thanks in advance.
You can use max and list comprehension.
result = [max(pair) for pair in zip(R1, R2)]
print result
Create a new list and append() the result:
In []:
R1=[10,20,30,40,50]
R2=[5,10,45,40,45]
results = []
for n, m in zip(R1,R2):
if n>m:
results.append(n)
else:
results.append(m)
results
Out[]:
[10, 20, 45, 40, 50]
You can look at a list comprehension to do the same thing:
In []:
results = [n if n>m else m for n, m in zip(R1, R2)]
results
Out[]:
[10, 20, 45, 40, 50]
Or even more simply:
In []:
results = [max(x) for x in zip(R1, R2)]
results
Out[]:
[10, 20, 45, 40, 50]
Functional solution
The map() and max() functions make short work of this problem:
>>> R1 = [10, 20, 30, 40, 50]
>>> R2 = [5, 10, 45, 40, 45]
>>> list(map(max, R1, R2))
[10, 20, 45, 40, 50]
List comprehension solution
Another technique to is to use a conditional expression in a list comprehension:
>>> [n if n>m else m for n, m in zip(R1, R2)]
[10, 20, 45, 40, 50]
R1=[10,20,30,40,50]
R2=[5,10,45,40,45]
temp_list = []
for n,m in zip(R1,R2):
if n>m:
temp_list.append(n)
else:
temp_list.append(m)
print(temp_list)
this should work.
you are trying to print each value, so it is printed on separate lines.
Use map with multiple iterables:
>>> R1=[10,20,30,40,50]
>>> R2=[5,10,45,40,45]
>>> it = map(max, R1, R2)
>>> print(list(it))
[10, 20, 45, 40, 50]
(Generally, the place to look is in the itertools module, but in this case the function is actually builtin).

Homework: How to split a new list into same length as input list?

For this assignment we were directed to write a program that will take two lists of lists and add the corresponding values together. For example, addTables([[1,8],[2,7],[3,6],[4,5]],[[9,16],[10,15],[11,14],[12,13]]) should return [[10, 24], [12, 22], [14, 20], [16, 18]].
My code is:
def addTables(list1, list2):
newlist = []
for i in range(0, len(list1)):
for j in range(0, len(list1[0])):
x = ([list1[i][j] + list2[i][j]])
newlist = newlist + x
return newlist
This gives me all the correct values, but displays them as one list [10, 24, 12, 22, 14, 20, 16, 18]. How can I preserve the structure of the original list?
To make your code work, create intermediate lists and append them:
def addTables(list1, list2):
newlist = []
for i in range(0, len(list1)):
sublist = []
for j in range(0, len(list1[0])):
x = list1[i][j] + list2[i][j]
sublist.append(x)
newlist.append(sublist)
return newlist
Or, you can also use zip():
>>> l1 = [[1,8],[2,7],[3,6],[4,5]]
>>> l2 = [[9,16],[10,15],[11,14],[12,13]]
>>> [[sum(subitem) for subitem in zip(*item)]
for item in zip(l1, l2)]
[[10, 24], [12, 22], [14, 20], [16, 18]]

How to return 2 separate lists from a single list?

If have this list here:
[25, 8, 22, 9]
How can I make the program create 2 seperate lists, and print them both? One should contain all the numbers less than 20, and the other needs to contain all the numbers greater than 20. The final print result should be displayed like this: [8, 9], [25, 22]
>>> predicates = lambda x:x<20, lambda x:x>20
>>> print [filter(pred, [25, 8, 22, 9]) for pred in predicates]
[[8, 9], [25, 22]]
Use list comprehensions:
>>> L = [25, 8, 22, 9]
>>> [x for x in L if x < 20]
[8, 9]
>>> [x for x in L if x > 20]
[25, 22]
def print_split_list(raw_list, split_value):
lower_list = [v for v in raw_list if v < split_value]
upper_list = [v for v in raw_list if v >= split_value]
print lower_list, upper_list
print_split_list([25, 8, 22, 9], 20) # => [8, 9] [25, 22]
a = [25, 8, 22, 9]
print [x for x in a if x > 20]
print [x for x in a if x < 20]
You use here list comprehensions. List comprehension looks like:
[ f(x) for x in a if cond(x) ]
That means: produce me a list that consists of f(x) for each element of x for that cond(x) is True.
In our case f(x)is simply x. And cond(x) is x > 20 or x < 20 (please note also that if you have 20s in your list, they will disappear from the result).
If it is a homework you can solve the task in more low-level way:
a = [25, 8, 22, 9]
list1 = []
list2 = []
for elem in a:
if elem > 20:
list1.append(elem)
if elem < 20:
list2.append(elem)
print list1
print list2
Here you iterate through the list and check its elements.
That elements that are greater than 20 you append to one list; and that that are lesser thatn 20 — to the other.
Note: the assumes you want twenty in listTwo
listOne = [x for x in yourList if x < 20]
listTwo = [x for x in yourList if x >= 20]
print listOne
print listTwo
Although you should use list comprehensions you might be interested in the for loop approach if you are starting with python
listOne = []
listOne = []
for x in yourList:
if x < 20:
listOne.append(x)
else:
listTwo.append(x)
li = [25, 8, 22, 9]
li.sort()
for i, x in enumerate(li):
if x > 20:
print li[:i]
print li[i:]
break

Categories