Home > Net >  Try to find a sublist that doesnt occur in the range of ANY of the sublists in another list
Try to find a sublist that doesnt occur in the range of ANY of the sublists in another list

Time:12-03

enhancerlist=[[5,8],[10,11]]
TFlist=[[6,7],[24,56]]

I have two lists of lists. I am trying to isolate the sublists in my 'TFlist' that don't fit in the range of ANY of the sublists of enhancerlist (by range: TFlist sublist range fits inside of enhancerlist sublist range). SO for example, TFlist[1] will not occur in the range of any sublists in enhancerlist (whereas TFlist [6,7] fits inside the range of [5,8]) , so I want this as output:

TF_notinrange=[24,56]

the problem with a nested for loop like this:

while TFlist:
   TF=TFlist.pop()
   for j in enhancerlist: 
       if ((TF[0]>= j[0]) and (TF[1]<= j[1])):
           continue
           
       else: 
           TF_notinrange.append(TF)
 

is that I get this as output: [[24, 56], [3, 4]]

the if statement is checking one sublist in enhancerlist at a time and so will append TF even if, later on, there is a sublist it is in the range of.

Could I somehow do a while loop with the condition? although it seems like I still have the issue of a nested loop appending things incorrectly ?

CodePudding user response:

You can use a nested for loop to solve this problem.

Currently you are appending TF to TF_notinrange if it does not fit in the range of the current sublist in enhancerlist. You should instead check if TF fits in the range of any of the sublists in enhancerlist.

Here is one way you can do this:

enhancerlist = [[5,8],[10,11]]
TFlist = [[6,7],[24,56]]
TF_notinrange = []

for TF in TFlist:
  in_range = False
  for j in enhancerlist:
    if ((TF[0]>= j[0]) and (TF[1]<= j[1])):
      in_range = True
      break

  if not in_range:
    TF_notinrange.append(TF)

print(TF_notinrange)

This should output [[24, 56]]

Hope this helps!

CodePudding user response:

Alternative is to use a list comprehension:

TF_notinrange = [tf for tf in TFlist 
                 if all(tf[0] < istart or tf[1] > iend 
                        for istart, iend in enhancerlist)]
print(TF_notinrange)
>>> TF_notinrange

Explanation

Take ranges of TFlist which are not contained in any ranges of enhancerlist

CodePudding user response:

You can use chained comparisons along with the less-common for-else block where the else clause triggers only if the for loop was not broken out of prematurely to achieve this:

non_overlapping = []

for tf_a, tf_b in TFlist:
    for enhancer_a, enhancer_b in enhancerlist:
        if enhancer_a <= tf_a < tf_b <= enhancer_b:
            break
    else:
        non_overlapping.append([tf_a, tf_b])

Note that this assumes that all pairs are already sorted and that no pair comprises a range of length zero (e.g., (2, 2)).

  • Related