divides each element of the matrix by 2 if the element is an even number - list-comprehension

i need to write a function in python that takes a matrix as an argument and divides each element of the matrix by 2 if the element is an even number (otherwise, does nothing).
i also need to use list comprehension for this.
as an example, if i have a matrix like m = [[5, 4], [2, 3], [6, 7]] output: [[5, 2], [1, 3], [3, 7]]
Thanks.

def f(matrix):
return [ [x//2 if x%2==0 else x for x in m ] for m in matrix]
print(f([[5, 4], [2, 3], [6, 7]]))

Related

Element wise addition of two n dimensional lists

When I need to add two 2D lists element wise, the approach I am using is
l1 = [[1, 1, 1],
[2, 2, 2],
[3, 3, 3]]
l2 = [[1, 1, 1],
[2, 2, 2],
[3, 3, 3]]
new = list(map(lambda e: [sum(x) for x in zip(*e)], zip(l1, l2)))
print(new)
output : [[2, 2, 2],
[4, 4, 4],
[6, 6, 6]]
This code is already difficult to read.
So how would I add two n dimensional lists element wise? Is there a pythonic way to do it or should I use numpy?

How to partially extract items in a list?

l = [[[[1,2,3],[4,5,6]],[[7,8,9],[10,11,12]]],[[[13,14,15],[16,17,18]],[[19,20,21],[22,23,24]]]]
l1=l[0][0][0] (i.e. [1, 2, 3])
l2=l[0][1][0] (i.e. [7, 8, 9])
Is there a quicker way to obtain a list of [[1, 2, 3],[7, 8, 9]] in one go, without reshuffling the original list?
Here are 2 ways to achieve that:
unpack to get get your wanted lists then put them together in a list
[[x, _], [y, _]] = l[0]
print([x, y])
output:
[[1, 2, 3], [7, 8, 9]]
use next and zip built-in functions:
print(list(next(zip(*l[0]))))
output:
[[1, 2, 3], [7, 8, 9]]

Iā€™m trying to flip every second sub list in a list of lists. Does any one have suggestions?

My_list= [[1,2,3],[4,5,6],[7,8,9]] ā€”ā€”ā€”-> [[1,2,3],[6,5,4],[7,8,9]]
I tried using this with out success :
for i my_list:
if my_list.index(i) != 0:
i = i[::-1]
Since Python for loops create local variables, you have to index into the outer list indexes and use % 2 == 1 to detect sublists with odd indexes.
my_list = [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]]
for index, sublist in enumerate(my_list):
if index % 2 == 1:
my_list[index] = sublist[::-1]
print(my_list)
Outputs
[[1, 2, 3], [6, 5, 4], [7, 8, 9], [12, 11, 10]]
Another option (in addition to #DeepSpace answer) is using Python's slicing notation (link) and assigning to slice (link):
In this example, we create slice starting from index 1 and step 2 and assign reverse sublist to it:
my_list = [[1,2,3],[4,5,6],[7,8,9]]
my_list[1::2] = (v[::-1] for v in my_list[1::2])
print(my_list)
Prints:
[[1, 2, 3], [6, 5, 4], [7, 8, 9]]

Reducing time complexity in comparing contiguous subarrays?

So say I have a list sequences such as this.
I want to remove all sequences where its total sum = N and/or it has a contiguous subarray with sum = N.
For example, if N = 4, then (1,1,2) is not valid since its total is 4. (1,1,3) is also not valid since the (1,3) is also 4. (1,3,1) is also not valid for the same reason.
lst = [
(1,1,1), (1,1,2), (1,1,3),
(1,2,1), (1,2,2), (1,2,3),
(1,3,1), (1,3,2), (1,3,3),
(2,1,1), (2,1,2), (2,1,3),
(2,2,1), (2,2,2), (2,2,3),
(2,3,1), (2,3,2), (2,3,3),
(3,1,1), (3,1,2), (3,1,3),
(3,2,1), (3,2,2), (3,2,3),
(3,3,1), (3,3,2), (3,3,3)
]
E.g.
Input: 4 3
Output: 2 1 2
So what I have right now is
lst = [t for t in list(product(range(1,n),repeat=n-1)) if not any((sum(t[l:h+1]) % n == 0) for l, h in combinations(range(len(t)), 2))]
Currently it is in O(n2) if I'm not mistaken. What would be a better way to do this?
If you can use numpy, you can concatenate the total sum of each tuple with the contiguous value sums, then check if any of your resultign elements are equal to 4:
arr = np.array(lst)
arr[~(np.concatenate((np.sum(arr,axis=1).reshape(-1,1),
(arr[:,:-1]+ arr[:,1:])),axis=1) == 4).any(1)]
# or:
arr[(np.concatenate((np.sum(arr,axis=1).reshape(-1,1),
(arr[:,:-1]+ arr[:,1:])),axis=1) != 4).all(1)]
Returning:
array([[1, 1, 1],
[1, 2, 3],
[2, 1, 2],
[2, 3, 2],
[2, 3, 3],
[3, 2, 1],
[3, 2, 3],
[3, 3, 2],
[3, 3, 3]])

Python - Generate list of lists from other list values

I need to generate a list of lists in that special way:
[3, 1, 4] -> [[1, 2, 3], [1], [1, 2, 3, 4]]
That means that every list in a list of lists must be in range of the given list values. I've tried smth like:
L = [3, 1, 4]
q = [i for i in L]
print(list([x] for x in range(y for y in q)))
But it return a TypeError: generator cannot be interpreted as an integer
That all has to be a single generator expression.
Using a list comprehension.
Try:
L = [3, 1, 4]
print([list(range(1, i+1)) for i in L])
Output:
[[1, 2, 3], [1], [1, 2, 3, 4]]

Resources