Groupby match into list of lists - python-2.7

I have two lists that have matching elements. For example:
L1 = [A, B]
L2 = [1_A, i_X, i_Y, 2_A, x_B, y_B, z_B]
I wish to group the matching factors into new list like the following:
match_grouplist = [[1_A, 2_A],[x_B, y_B, z_B]]
I tried,
pull = []; tmp = []
for entry in range(len(L1)):
spp = L[entry]
for ele in L2:
if ele.split("_")[1] == spp:
tmp.append(ele)
pull.extend(tmp)
It produces only a list. Can anyone suggest how to make this a list of list ?
Thanks in Advance,
AP

Here is a solution using list comprehensions :
[ [e2 for e2 in L2 if e2.endswith('_'+e1)] for e1 in L1 ]
This means that for each element e1 of L1 we will look for the elements of L2 that end with _e1, and return it.
The result is [['1_A', '2_A'], ['x_B', 'y_B', 'z_B']]

Related

How do you multiply each number in a list with each number in another list

I have two lists:
list1 = [1,2,3]
list2 = [4,5,6]
I want to multiply each number in the first list with each number in the second list to get the result:
list3 = [4,5,6,8,10,12,12,15,18]
How do I do this?
There could be a more pythonic way to do this but this gets the job
done.
lst1 = [1,2,3]
lst2 = [4,5,6]
lst3 = []
for i in lst1:
for j in lst2:
lst3.append(i*j)
print(lst3)
Using list comprehension:
print([(l1*l2) for l1 in lst1 for l2 in lst2])

How to remove an item from a list in python with substring match

I have got a list l1 = ['00001MMYYYSSSS', '00002YYSSMMYNNN', '00003FFMMNNNSS'] and another list
l2 = ['00001', '00003']. I need to remove the items at index 0 and 2 in the list l1 as it contains the string given in l2. How do I go about doing this?
I have tried the solutions mentioned [here]Is there a simple way to delete a list element by value? and
[here]Python: subset elements in one list based on substring in another list, retain only one element per substring but they return an empty list. Thank you!
This should work:
l1 = ['00001MMYYYSSSS', '00002YYSSMMYNNN', '00003FFMMNNNSS']
l2 = ['00001', '00003']
l_result = [x for x in l1 if not any(l in x for l in l2)] # ['00002YYSSMMYNNN']
# Hello World program i
l1 = ['00001MMYYYSSSS', '00002YYSSMMYNNN', '00003FFMMNNNSS']
l2 = ['00001', '00003']
L3=[]
for el in l2:
for el1 in l1:
if el in el1:
L3.append(el1)
for l3 in L3:
l1.remove(l3)
print l1

OCaml -- how to check if two lists match

Say I have two lists:
let l1 = [1;2;3];;
let l2 = [1;2;3];;
I am trying to check if they have the same values and order, but if I do
l1 == l2;;
I get false. How do I check if they have the same values in the same order?
Never mind. I forgot that = was different in OCaml.
list1 = list2
returns true...

Check element in a list

I have an example:
let l = [0;1;2]
let l1 = [0;2]
From the list l check that whether or not there are some element of l is belong to l1; if yes then return a list of pair, for instance [(1,0); (1;2)]
For this, you should iterate through each element in l. Then check if the first element of l is an element of l1. If it is, filter out all the elements that are equal. Then get the length of list of equal elements which will be the first character in the tuple that will go into the return list.
let check_list l l1 =
let rec check l l1 combined =
match l with
|[] -> combined
|(h::t) -> if (List.mem h l1) then
check t l1 ((List.length(List.filter (fun x -> h=x) l1),h)::combined)
else check t l1 combined
in check l l1 []
What exactly are you trying to do?
Counting the number of occurrences of each element from l in l1?
One idea might be to ask yourself, how do I do it for one element of l?
For this purpose, you might want to make a function with the following signature: nb_mem : 'a -> 'a list -> int.
Then to produce your list, you could do it recursively.
let rec check l l1 =
match l with
| [] -> []
| e :: r -> let nb = nb_mem e l1 in
if nb = 0 then check r l1 else (nb,e) :: (check r l1)
Of course, this doesn't take into account the fact that an element might appear several times in l and is far from being optimal.
One idea might be to sort both of your lists (in case you are working with integer values it is easy) before to avoid reading l1 entirely multiple times.
You could also go for a hashtbl containing the number of occurrences of each element in l1 and then producing your list by reading the corresponding entries for each element of l.

Haskell: List to Rose Tree

Consider the following type to represent Rose trees:
data RTree a = No a [RTree a]
Consider the function
tolist a = tolistAux 1 a
where tolistAux n (No x l) = (x,n) : (concat (map (tolistAux (n+1)) l))
I need to define the inverse of the first function: unlist :: [(a,Int)] -> RTree a
such that unlist (tolist a) = a
Here is the solution I found.
I realized that if in (a,b), b==1 then I create a No a (...)
Thus, I have a list and isolate this list into several lists that start with (a,1) by first subtracting 1 to b.
Then, I create the tree using recursion (e,g a map function):
unlist ((x,1):t) = No x l3
where l1 = map (\(a,b) -> (a,b-1)) t
l2 = isolate1 l1
l3 = map unlist l2
isolate1 :: [(a,b)]->[[(a,b)]] --note that the result of isolate1 is a list of lists of pairs
isolate1 [] = []
isolate [x]=[[x]]
isolate1 ((a,b):t) = let (x:xs):ys = isolate1 t
in |b==1 = ((a,b):x:xs):ys
|otherwise = [(a,b)]:(x:xs):ys
Glad to see more solutions :)