For loop variable initialisation from a list - groovy

Groovy allows unfolding lists in assignment, as in:
(x, y) = [1, 2]
So I assumed something similar would work in a for loop, as in:
list = [[1, 2], [2, 4], [3, 6]]
for ((elm1, elm2) in list) {...}
Which turns out to be a syntax error. Is this style not possible or is there some trick to it I'm missing?

I guess it won't work with the for loop (or I definitely don't know the syntax), however a two-argument closure can be used to iterate such a List, unfold the tuples:
def list = [[1, 2], [2, 4], [3, 6]]
assert list.collect { a, b -> a + b } == [3, 6, 9, ]

Related

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

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]]))

Unflattening list returns unexpected Error in Python

I have read all the posts about unflattening lists on Stackoverflow but I can't find a solution to my problem.
I have two lists and I want to add one element from list2 to every element in list1.
l1 = [[1,2],[3,4]]
l2 = [5, 7]
and the result I am after is
[[1, 2, 5], [3, 4, 6]]
I have tried this code
for i in range(len(l2)):
l1[i].extend(l2[i])
print(l1)
but returns an Error "TypeError: 'int' object is not iterable"
When every element of l2 is a list by itself e.g. l2 = [[5],[7]]
my code works fine. Why is that? And how do I adjust my code to work when l2 is in this format l2 = [5, 7]
Use zip() to iterate over two or more things in parallel. Using range() to make indexes when you don't need them is unpythonic.
xss = [[1,2],[3,4]]
ys = [5,7]
for xs, y in zip(xss, ys):
xs.append(y)
print(xss)
[[1, 2, 5], [3, 4, 7]]
list1.extend(list2) is to create list1+list2. But you are not providing list2, instead, it is just an element. The right function to do that is list1.append(element2), which is same as list1+[element2]
l1 = [[1,2],[3,4]]
l2 = [5, 7]
for i in range(len(l2)):
l1[i].append(l2[i]);
print(l1)
[[1, 2, 5], [3, 4, 7]]
Extend is for objects.
Append is what you need here.

How to transform a list of lists like [1, [2, 3, 4], 5 ] to a list [[1,2,5], [1,3,5], [1,4,5]] in Python?

I'm just starting with Python and trying to find a general solution to transform a list of lists [1, [2, 3, 4], 5 ] to a list [[1,2,5], [1,3,5], [1,4,5]] in Python.
I've tried creating some dynamic lists but not getting what i want, not even for this simple list in the example. Any help will be greatly appreciated.
inter_l = []
aba = []
v = [1, [2, 3], 4, 5, 6]
g = globals()
for elem in v:
if isinstance(elem, (list,)):
l_ln = len(elem)
indx = v.index(elem)
for i in range(0, l_ln):
g['depth_{0}'.format(i)] = [elem[i]]
inter_l.append(list(g['depth_{0}'.format(i)]))
else:
aba.append(elem)
t = aba.extend(inter_l)
w = aba.extend(inter_l)
print(v)
print(aba)
print(inter_l)
[1, [2, 3], 4, 5, 6]
[1, 4, 5, 6, [2], [3], [2], [3]]
[[2], [3]]
The easiest way would be to leverage itertools.product function, but since it expects iterables as its inputs, the input would have to be transformed a little. One way to achieve this would be something like this:
transformed = [e if isinstance(e, list) else [e] for e in v]
which converts all non-list elements into lists and then pass this transformed input to product:
list(itertools.product(*transformed))
Note, that * in front of transformed expands transformed list into positional arguments, so that instead of a single argument of type list, a list of its elements is passed instead.
The entire pipeline looks something like this:
>>> v = [1, [2, 3, 4], 5]
>>> t = [e if isinstance(e, list) else [e] for e in v]
>>> list(itertools.product(*t))
[(1, 2, 5), (1, 3, 5), (1, 4, 5)]

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]]

Summing two 2-D lists

so this has kind of stumped me. I feel like it should be an easy problem though.
Lets say I have these two lists
a = [[3, 4], [4, 5]]
b = [[1, 2], [4, 6]]
I am trying so it would return the sum of the two 2-D lists of each corresponding element like so
c = [[4, 6], [8, 11]]
I am pretty sure I am getting lost in loops. I am only trying to use nested loops to produce an answer, any suggestions? I'm trying several different things so my code is not exactly complete or set in stone and will probably change by the time someone reponds so I won't leave a code here. I am trying though!
You could try some variation on nested for-loops using enumerate (which will give you the appropriate indices for comparison to some other 2d array):
a = [[3, 4], [4, 5]]
b = [[1, 2], [4, 6]]
Edit: I didn't see you wanted to populate a new list, so I put that in there:
>>> c = []
>>> for val, item in enumerate(a):
newvals = []
for itemval, insideitem in enumerate(item):
newvals.append(insideitem + b[val][itemval])
c.append(newvals)
newvals = []
Result:
>>> c
[[4, 6], [8, 11]]
Use numpy:
import numpy as np
a = [[3, 4], [4, 5]]
b = [[1, 2], [4, 6]]
c = np.array((a,b))
np.sum(c, axis=0)
I know it is an old question, but following nested loops code works exactly as desired by OP:
sumlist = []
for i, aa in enumerate(a):
for j, bb in enumerate(b):
if i == j:
templist = []
for k in range(2):
templist.append(aa[k]+bb[k])
sumlist.append(templist)
templist = []
print(sumlist)
Output:
[[4, 6], [8, 11]]

Resources