List of Lists as result in list comprehension - python

I am trying to find a solution for a problem where I have to loop in a list for every element.
This is not the real problem that I am trying to solve, but I am using a simple example to illustrate the problem and what I want to understand.
aList= [3, 4, 5, 6, 8, 9, 10,12]
I should regroup number divisible by each others.
result should give:
result = [[3], [4], [5], [6,3], [4,8],[3,9], [5,10], [3,4,6,12]]
I use this function:
def divisible(x,y):
if x%y== 0:
return True
else:
return False
well, to solve this problem using two loops, we can use:
globaList= []
for x in aList:
internalist=[]
internalist.append(x)
for y in aList:
if divisible(x,y):
internalist.append(y)
globaList.append(internalist)
I tried to write this double-loops in list comprehension, but didn't know how to make better way.
result= [[x for x in aList ] for y in aList if divisible(x,y) ]

def divisible(x,y):
if x%y== 0:
return True
else:
return False
aList= [3, 4, 5, 6, 8, 9, 10,12]
>>> [[x for x in aList if divisible(y,x)] for y in aList]
[[3], [4], [5], [3, 6], [4, 8], [3, 9], [5, 10], [3, 4, 6, 12]]

You don't really need a helper function divisible:
aList= [3, 4, 5, 6, 8, 9, 10,12]
print [[x for x in aList if y % x == 0] for y in aList]
If you really want to use a helper function you can make that more succinct by going:
def divisible(x,y):
return x % y == 0

Related

Find the next number value after a sublist in a list

I have two lists called x and y.
x = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
y = [4, 5]
I am trying to find the list that starts with y and get the following item (6 in this case). Also, i want to do this with a custom function. It must work like below
my_func(y)
takes the y and returns the number that comes next and equalize a variable to the number. Like, variable = 6
Although you can do this with lists and loops, it is probably quickest to do it with numpy arrays:
import numpy as np
def get_next_value(x, y):
x = np.array(x)
y = np.array(y)
num_to_check = y.shape[0]
row_to_get_value = np.where((x[:,0:num_to_check] == y).sum(axis = 1) == num_to_check)
desired_value = x[row_to_get_value, num_to_check]
# Handle error if no match is found
if desired_value.size > 0:
return desired_value.item()
else:
return None
x = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
y = [4, 5]
get_next_value(x, y)
# 6
IIUC, this should work for you:
x = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
y = [4, 5]
def my_func(y):
output, ly = [], len(y)
for l in x:
if l[:ly] == y: output.append(l[ly])
return output
my_func(y)
Output:
[6]

How to properly structure a for loop for looping through python list

Let's say I have a list A = [1,2,3,4]
I want to show the lists [1,2,3] , [2,3,4]
Here's my solution:
A= [5, 3, 3]
def solution(A):
A.sort()
#print(A)
for i in range(0,len(A)-2):
if i+3 <= len(A):
part = A[i:i+3]
if part[0] + part[1] > part[2]:
print(part)
return 1
I used if i+3 <= len(A):
condition to check length overflow.I don't like the structure, is there a better way to represent this?
This is probably what you want.
for a in range(len(A)-2):
print(list(A[a:a+3]))
>>> [list(A[a:a+3]) for a in range(len(A)-2)]
[[1, 2, 3], [2, 3, 4], [3, 4, 5], [4, 5, 6], [5, 6, 7], [6, 7, 8], [7, 8, 9]]

creating combinations from a list of lists

Im trying to figure out how to take a list of lists of integers and create a new list that contains combinations from the list of lists. I want the combination to start with a value from the first list and then respectively take 1 from each of the subsequent lists, only if the value is greater than the previous list.
l=[[1,2,3],[4,8],[5,10]]
# the answer would look like this
correct=[[1,4,5],[1,4,10],[1,8,10],[2,4,5],[2,4,10],[2,8,10],[3,4,5],[3,4,10],[3,8,10]]
>>> from itertools import product
...
...
... def combos(lst):
... result = []
... for p in product(*lst):
... if all(a < b for a, b in zip(p, p[1:])):
... result.append(list(p))
... return result
...
>>> lst = [[1, 2, 3], [4, 8], [5, 10]]
>>> correct = [[1, 4, 5], [1, 4, 10], [1, 8, 10], [2, 4, 5], [2, 4, 10],
... [2, 8, 10], [3, 4, 5], [3, 4, 10], [3, 8, 10]]
>>> combos(lst) == correct
True
List comprehension is probably a great way to go. It works nicely because of your constraints. You probably want something like:
[[i,j,k] for i in l[0] for j in l[1] if j>i for k in l[2] if k>j]
>>> [[1, 4, 5],
[1, 4, 10],
[1, 8, 10],
[2, 4, 5],
[2, 4, 10],
[2, 8, 10],
[3, 4, 5],
[3, 4, 10],
[3, 8, 10]]
This makes a list of lists of the form [i,j,k] for all the i's in l[0] for all the j's in l[1] if j>i and for all the k's in l[2] if k>j (since we already know that j>i at this point)
However, the code above only works for an input list of list of length 3. Took me a little bit, but this recursive approach should work for a input list of any length
def list_of_lists(in_list):
full_list=[]
def recurse(so_far, l):
if l==len(in_list):
return so_far
next_list = in_list[l]
for i in next_list:
if i>so_far[-1]:
new_list = recurse(so_far.copy()+[i], l+1)
if new_list:
full_list.append(new_list)
for i in in_list[0]:
recurse([i],1)
return full_list
l=[[1,2,3],
[4,8],
[5,10]]
ansList = []
for i in range(len(l[0])):
for j in range(len(l[1])):
for k in range(len(l[2])):
if l[0][i]<l[1][j] and l[1][j]<l[2][k]:
ansList.append([l[0][i],l[1][j],l[2][k]])
print(ansList)

Convert simple list comprehension into for loops

My objective is transform this list comprehension into for loops :
[[x * y for x in [1, 2]] for y in [3, 4, 5]]
# gives [[3,6], [4,8], [5,10]]
The only thing i can find :
List = []
for y in [3, 4, 5]:
for x in [1, 2]:
List.append([y * x])
# Gives [[3], [6], [4], [8], [5], [10]]
I feel silly but i struggle to find the solution.
You need a temporary list in between the for-loops:
List = []
for y in [3, 4, 5]:
l = []
for x in [1, 2]:
l.append(x*y)
List.append(l)
Output:
[[3, 6], [4, 8], [5, 10]]
Take out the square brackets
List = []
for y in [3, 4, 5]:
for x in [1, 2]:
List.append(y * x)
Adding a square bracket around a calculation makes it a list in python

Python: One-liner to perform an operation upon elements in a 2d array (list of lists)?

I have a list of lists, each containing a different number of strings. I'd like to (efficiently) convert these all to ints, but am feeling kind of dense, since I can't get it to work out for the life of me. I've been trying:
newVals = [int(x) for x in [row for rows in values]]
Where 'values' is the list of lists. It keeps saying that x is a list and can therefore not be the argument if int(). Obviously I'm doing something stupid here, what is it? Is there an accepted idiom for this sort of thing?
This leaves the ints nested
[map(int, x) for x in values]
If you want them flattened, that's not hard either
for Python3 map() returns an iterator. You could use
[list(map(int, x)) for x in values]
but you may prefer to use the nested LC's in that case
[[int(y) for y in x] for x in values]
How about:
>>> a = [['1','2','3'],['4','5','6'],['7','8','9']]
>>> [[int(j) for j in i] for i in a]
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
Another workaround
a = [[1, 2, 3], [7, 8, 6]]
list(map(lambda i: list(map(lambda j: j - 1, i)), a))
[[0, 1, 2], [6, 7, 5]] #output
You simply use incorrect order and parenthesis - should be:
inputVals = [['1','2','3'], ['3','3','2','2']]
[int(x) for row in inputVals for x in row]
Or if you need list of list at the output then:
map(lambda row: map(int, row), inputVals)
an ugly way is to use evalf:
>>> eval(str(a).replace("'",""))
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
if you don't mind all your numbers in one array you could go:
>>> a = [['1','2','3'],['4','5','6'],['7','8','9']]
>>> map(int,sum(a,[]))
[1, 2, 3, 4, 5, 6, 7, 8, 9]
In order to map list with any number of dimensions you could use numpy.apply_over_axes
import numpy as np
np.apply_over_axes(lambda x,_:x*2, np.array([[1,2,3],[5,2,1]]),[0])
--------------------
array([[ 2, 4, 6],
[10, 4, 2]])
Unfortunately that doesn't work if you also need to change variable type. Didn't find any library solution for this, so here is the code to do that:
def map_multi_dimensional_list(l, transform):
if type(l) == list and len(l) > 0:
if type(l[0]) != list:
return [transform(v) for v in l]
else:
return [map_multi_dimensional_list(v, transform) for v in l]
else:
return []
map_multi_dimensional_list([[[1,2,3],[5,2,1]],[[10,20,30],[50,20,10]]], lambda x:x*2)
------------------
[[[2, 4, 6], [10, 4, 2]], [[20, 40, 60], [100, 40, 20]]]

Categories